﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

using GRWL.BZSC.DataLinq;
using System.Reflection;
using System.Collections;
using System.Data.Linq.SqlClient;
using System.Security.Cryptography;
using System.Data.Linq;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;

namespace GRWL.BZSC.WCFLib
{
    // 注意: 如果更改此处的类名 "BaseData"，也必须更新 App.config 中对 "BaseData" 的引用。
    public class BaseData : IBaseData
    {
        //实例化linq to sql类  
        GRWL.BZSC.DataLinq.BaseDataDataContext dc = new GRWL.BZSC.DataLinq.BaseDataDataContext();

        #region IBaseData 成员

        #region 基础数据部分

        #region 通用选项管理

        /// <summary>
        /// 获取单个选项信息
        /// </summary>
        /// <param name="id">选项系统编号</param>
        /// <returns>选项对象</returns>        
        public TB_Options GetOption(int id)
        {
            return dc.TB_Options.SingleOrDefault(d => d.id == id && !d.deleteFlag);
        }

        /// <summary>
        /// 获取单个选项信息
        /// </summary>
        /// <param name="type">选项类型</param>
        /// <param name="name">选项名称</param>
        /// <returns>选项对象</returns>        
        public TB_Options GetOptionByTpNm(string type, string name)
        { return dc.TB_Options.SingleOrDefault(d => d.type == type && d.name == name && !d.deleteFlag); }

        /// <summary>
        /// 获取选项树形关系
        /// </summary>
        /// <returns>TB_Options</returns>
        public IEnumerable<TB_Options> GetOptionTree(string type)
        {
            return (from c in dc.TB_Options where c.type == type && !c.deleteFlag orderby c.sort select c);
        }

        /// <summary>
        /// 查找选项
        /// </summary>
        /// <param name="type">选项类型</param>
        /// <param name="code">选项代号</param>
        /// <param name="name">选项名称</param>
        /// <returns>TB_Options</returns>        
        public IEnumerable<TB_Options> FindOptions(string type, string code, string name)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Options>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (type != null)
                    predicate = predicate.And(p => p.type == type);

                if (!string.IsNullOrEmpty(name))
                    predicate = predicate.And(p => p.name.Contains(name));

                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));
                return dc.TB_Options.Where(predicate);
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增选项
        /// </summary>
        /// <param name="option">选项</param>
        /// <returns>新建选项系统编号</returns>
        public int AddOption(TB_Options option)
        {
            try
            {
                dc.TB_Options.InsertOnSubmit(option);
                dc.SubmitChanges();
                return option.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新一个选项
        /// </summary>
        /// <param name="option">选项类</param>
        /// <returns>是否更新成功</returns>
        public bool UpdateOption(TB_Options option)
        {
            try
            {
                var o = dc.TB_Options.SingleOrDefault(d => d.id == option.id);
                if (o != null)
                {
                    Common.objEval(option, o);
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除一个选项
        /// </summary>
        /// <param name="id">选项系统编号</param>
        /// <returns>是否删除成功</returns>
        public bool DeleteOption(int id)
        {
            try
            {
                var data = dc.TB_Options.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    //dc.TB_Options.DeleteOnSubmit(data);
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 往来单位管理

        /// <summary>
        /// 获取单个往来单位信息
        /// </summary>
        /// <param name="id">往来单位系统编号</param>
        /// <returns>往来单位对象</returns>
        public TB_Trader GetTrader(int id)
        { return dc.TB_Trader.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取一类往来单位
        /// </summary>
        /// <param name="type">类型编号</param>
        /// <returns>往来单位序列</returns>
        public IEnumerable<TB_Trader> GetTraders(int type)
        {
            return (from c in dc.TB_Trader where c.type == type && !c.deleteFlag select c);
        }

        /// <summary>
        /// 搜索往来单位
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="isSupplier">是否供应商</param>
        /// <param name="isClient">是否客户</param>
        /// <param name="name">名称</param>
        /// <param name="linkman">联系人</param>
        /// <returns>往来单位序列</returns>
        public IEnumerable<TB_Trader> FindTraders(int? type, bool? isSupplier, bool? isClient, string code, string name, string linkman)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Trader>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (type != null)
                    predicate = predicate.And(p => p.type == type);

                if (isSupplier != null)
                    predicate = predicate.And(p => p.isSupplier == isSupplier);

                if (isClient != null)
                    predicate = predicate.And(p => p.isClient == isClient);

                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                if (!string.IsNullOrEmpty(name))
                    predicate = predicate.And(p => p.name.Contains(name));

                if (!string.IsNullOrEmpty(linkman))
                    predicate = predicate.And(p => p.linkman.Contains(linkman));
                return dc.TB_Trader.Where(predicate);
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增往来单位
        /// </summary>
        /// <param name="trader">往来单位</param>
        /// <returns>新建选项系统编号</returns>
        public int AddTrader(TB_Trader trader)
        {
            try
            {
                dc.TB_Trader.InsertOnSubmit(trader);
                dc.SubmitChanges();
                return trader.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新一个往来单位
        /// </summary>
        /// <param name="trader">往来单位类</param>
        /// <returns>是否更新成功</returns>
        public bool UpdateTrader(TB_Trader trader)
        {
            try
            {
                var o = dc.TB_Trader.SingleOrDefault(d => d.id == trader.id);
                if (o != null)
                {
                    Common.objEval(trader, o, new List<string> { typeof(TB_Order).Name, typeof(TB_Quotation).Name, typeof(TB_QC).Name, typeof(TB_Shipping).Name });
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除一个往来单位
        /// </summary>
        /// <param name="id">往来单位系统编号</param>
        /// <returns>是否删除成功</returns>
        public bool DeleteTrader(int id)
        {
            try
            {
                var data = dc.TB_Trader.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    //dc.TB_Trader.DeleteOnSubmit(data);
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 物料管理

        /// <summary>
        /// 获取单个物料信息
        /// </summary>
        /// <param name="id">物料系统编号</param>
        /// <returns>物料对象</returns>        
        public TB_Material GetMaterial(int id)
        {
            return dc.TB_Material.SingleOrDefault(d => d.id == id && !d.deleteFlag);
        }

        /// <summary>
        /// 获取单个物料信息附带关联信息
        /// </summary>
        /// <param name="id">物料id</param>
        /// <param name="stockId">仓库id</param>
        /// <param name="batchNo">出入仓批次</param>
        /// <returns>XMaterial</returns>
        public XMaterial GetXMaterial(int id, int? stockId, string batchNo)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Material>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var predicate1 = PredicateBuilder.True<TB_Stock>();
                predicate1 = predicate1.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(batchNo))
                    predicate1 = predicate1.And(p => p.batchNo == batchNo);

                if (stockId != null)
                {
                    predicate1 = predicate1.And(p => p.id == stockId);

                    var query = from m in dc.TB_Material.Where(predicate)
                                join c in dc.TB_Options on m.category equals c.id into t_Category
                                from tc in t_Category.DefaultIfEmpty()
                                join u in dc.TB_Options on m.unit equals u.name into t_Unit
                                from tu in t_Unit.DefaultIfEmpty()
                                join p in dc.TB_Trader on m.provider equals p.id into t_Provider
                                from tp in t_Provider.DefaultIfEmpty()
                                join d1 in dc.TB_Depot on m.depot equals d1.id into t_Depot
                                from td1 in t_Depot.DefaultIfEmpty()
                                join d2 in dc.TB_Depot on m.waitingDepot equals d2.id into t_WaitingDepot
                                from td2 in t_WaitingDepot.DefaultIfEmpty()
                                join d3 in dc.TB_Depot on m.badDepot equals d3.id into t_BadDepot
                                from td3 in t_BadDepot.DefaultIfEmpty()
                                join d4 in dc.TB_Depot on m.scrapDepot equals d4.id into t_ScrapDepot
                                from td4 in t_ScrapDepot.DefaultIfEmpty()
                                join d5 in dc.TB_Department on m.department equals d5.id into t_Department
                                from td5 in t_Department.DefaultIfEmpty()
                                join s in (dc.TB_Stock.Where(predicate1)) on m.id equals s.material into t_stock
                                from ss in t_stock.DefaultIfEmpty()
                                join d6 in dc.TB_Depot on ss.depot equals d6.id into t_stockDepot
                                from td6 in t_stockDepot.DefaultIfEmpty()
                                join w in dc.TB_Workstage on m.workstage equals w.id into t_workstage
                                from ww in t_workstage.DefaultIfEmpty()
                                select new XMaterial()
                                {
                                    Material = m,
                                    StockId = ss.id,
                                    StockDepotName = td6.name,
                                    CurrentStockNum = ss.num,
                                    BeginningNum = ss.beginningNum,
                                    DepotArea = ss.area,
                                    BatchNo = ss.batchNo,
                                    CategoryCode = tc.code,
                                    CategoryName = tc.name,
                                    TraderName = tp.name,
                                    DepotCode = td1.code,
                                    DepotName = td1.name,
                                    WaitingDepotCode = td2.code,
                                    WaitingDepotName = td2.name,
                                    BadDepotCode = td3.code,
                                    BadDepotName = td3.name,
                                    ScrapDepotCode = td4.code,
                                    ScrapDepotName = td4.name,
                                    DepartmentCode = td5.code,
                                    DepartmentName = td5.name,
                                    WorkstageCode = ww.code,
                                    WorkstageName = ww.name
                                };
                    return query.First();
                }
                else
                {
                    var query = from m in dc.TB_Material.Where(predicate)
                                join c in dc.TB_Options on m.category equals c.id into t_Category
                                from tc in t_Category.DefaultIfEmpty()
                                join u in dc.TB_Options on m.unit equals u.name into t_Unit
                                from tu in t_Unit.DefaultIfEmpty()
                                join p in dc.TB_Trader on m.provider equals p.id into t_Provider
                                from tp in t_Provider.DefaultIfEmpty()
                                join d1 in dc.TB_Depot on m.depot equals d1.id into t_Depot
                                from td1 in t_Depot.DefaultIfEmpty()
                                join d2 in dc.TB_Depot on m.waitingDepot equals d2.id into t_WaitingDepot
                                from td2 in t_WaitingDepot.DefaultIfEmpty()
                                join d3 in dc.TB_Depot on m.badDepot equals d3.id into t_BadDepot
                                from td3 in t_BadDepot.DefaultIfEmpty()
                                join d4 in dc.TB_Depot on m.scrapDepot equals d4.id into t_ScrapDepot
                                from td4 in t_ScrapDepot.DefaultIfEmpty()
                                join d5 in dc.TB_Department on m.department equals d5.id into t_Department
                                from td5 in t_Department.DefaultIfEmpty()
                                join w in dc.TB_Workstage on m.workstage equals w.id into t_workstage
                                from ww in t_workstage.DefaultIfEmpty()
                                select new XMaterial()
                                {
                                    Material = m,
                                    StockId = null,
                                    StockDepotName = null,
                                    CurrentStockNum = null,
                                    BeginningNum = null,
                                    DepotArea = null,
                                    BatchNo = null,
                                    CategoryCode = tc.code,
                                    CategoryName = tc.name,
                                    TraderName = tp.name,
                                    DepotCode = td1.code,
                                    DepotName = td1.name,
                                    WaitingDepotCode = td2.code,
                                    WaitingDepotName = td2.name,
                                    BadDepotCode = td3.code,
                                    BadDepotName = td3.name,
                                    ScrapDepotCode = td4.code,
                                    ScrapDepotName = td4.name,
                                    DepartmentCode = td5.code,
                                    DepartmentName = td5.name,
                                    WorkstageCode = ww.code,
                                    WorkstageName = ww.name
                                };
                    return query.SingleOrDefault();
                }
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 查找物料
        /// </summary>
        /// <param name="stockNullable">库存出入可以为空</param>
        /// <param name="type">类型</param>
        /// <param name="depotCategory">仓库类型</param>
        /// <param name="depot">仓库</param>
        /// <param name="code">代码</param>
        /// <param name="name">名称</param>
        /// <param name="specs">规格</param>
        /// <param name="source">来源</param>
        /// <param name="isPurchase">是否采购件</param>
        /// <param name="isNominal">是否虚设件</param>
        /// <returns>物料对象序列</returns>        
        public IEnumerable<QMaterial> FindMaterials(bool? stockNullable, int? type, int? depotCategory, int? depot, string code, string name, string specs, string source, bool? isPurchase, bool? isNominal)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Material>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (type != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(type.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(type));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate = predicate.And(p => ary.Contains(p.category.ToString()));
                }

                if (isPurchase!=null)
                    predicate = predicate.And(p => p.isPurchase == isPurchase);

                if (isNominal != null)
                    predicate = predicate.And(p => p.isNominal == isNominal);

                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                if (!string.IsNullOrEmpty(name))
                    predicate = predicate.And(p => p.cnName.Contains(name));

                if (!string.IsNullOrEmpty(specs))
                    predicate = predicate.And(p => p.specs.Contains(specs));

                if (!string.IsNullOrEmpty(source))
                    predicate = predicate.And(p => p.source==source);


                var predicate1 = PredicateBuilder.True<TB_Depot>();
                predicate1 = predicate1.And(p => !p.deleteFlag);
                if (depot != null)
                {
                    predicate1 = predicate1.And(p => p.id == depot);
                }

                if (depotCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(depotCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.仓库分类.ToString(), Convert.ToInt32(depotCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate1 = predicate1.And(p => ary.Contains(p.type.ToString()));
                }

                var predicate2 = PredicateBuilder.True<TB_Stock>();
                predicate2 = predicate2.And(p => !p.deleteFlag);

                if (stockNullable == true)
                {
                    if (depotCategory == null && depot == null)
                    {
                        var query = from m in (dc.TB_Material.Where(predicate))
                                    join d1 in dc.TB_Department on m.department equals d1.id into t_department
                                    from dd1 in t_department.DefaultIfEmpty()
                                    join t in dc.TB_Trader on m.provider equals t.id into t_trader
                                    from tt in t_trader.DefaultIfEmpty()
                                    join s in dc.TB_Stock on m.id equals s.material into t_stock
                                    from ss in t_stock.DefaultIfEmpty()
                                    join d2 in (dc.TB_Depot.Where(predicate1)) on ss.depot equals d2.id into t_stockDepot
                                    from dd2 in t_stockDepot.DefaultIfEmpty()
                                    join c in dc.TB_Options on m.category equals c.id into t_category
                                    from cc in t_category.DefaultIfEmpty()
                                    select new QMaterial()
                                    {
                                        Id = m.id,
                                        Code = m.code,
                                        CnName = m.cnName,
                                        Specs = m.specs,
                                        StockId = ss.id,
                                        StockDepotName = dd2.name,
                                        CurrentStockNum = ss.num,
                                        DepotArea = ss.area,
                                        BatchNo = ss.batchNo,
                                        Expire = m.expire,
                                        DepartmentCode = dd1.code,
                                        DepartmentName = dd1.name,
                                        Brand = m.brand,
                                        Unusable = m.unusable,
                                        Unit = m.unit,
                                        ProviderCode = tt.code,
                                        ProviderName = tt.name,
                                        Source = m.source,
                                        PrjtId = m.projectId,
                                        PrjtCode = m.projectCode,
                                        CategoryName = cc.name
                                    };
                        return query;
                    }
                    else
                    {
                        var query = from m in (dc.TB_Material.Where(predicate))
                                    join d1 in dc.TB_Department on m.department equals d1.id into t_department
                                    from dd1 in t_department.DefaultIfEmpty()
                                    join t in dc.TB_Trader on m.provider equals t.id into t_trader
                                    from tt in t_trader.DefaultIfEmpty()
                                    join s in dc.TB_Stock on m.id equals s.material into t_stock
                                    from ss in t_stock.DefaultIfEmpty()
                                    join d2 in (dc.TB_Depot.Where(predicate1)) on ss.depot equals d2.id
                                    join c in dc.TB_Options on m.category equals c.id into t_category
                                    from cc in t_category.DefaultIfEmpty()
                                    select new QMaterial()
                                    {
                                        Id = m.id,
                                        Code = m.code,
                                        CnName = m.cnName,
                                        Specs = m.specs,
                                        StockId = ss.id,
                                        StockDepotName = d2.name,
                                        CurrentStockNum = ss.num,
                                        DepotArea = ss.area,
                                        BatchNo = ss.batchNo,
                                        Expire = m.expire,
                                        DepartmentCode = dd1.code,
                                        DepartmentName = dd1.name,
                                        Brand = m.brand,
                                        Unusable = m.unusable,
                                        Unit = m.unit,
                                        ProviderCode = tt.code,
                                        ProviderName = tt.name,
                                        Source = m.source,
                                        PrjtId = m.projectId,
                                        PrjtCode = m.projectCode,
                                        CategoryName = cc.name
                                    };
                        return query;
                    }
                }
                else if (stockNullable == false)
                {
                    if (depotCategory == null && depot == null)
                    {
                        var query = from m in (dc.TB_Material.Where(predicate))
                                    join d1 in dc.TB_Department on m.department equals d1.id into t_department
                                    from dd1 in t_department.DefaultIfEmpty()
                                    join t in dc.TB_Trader on m.provider equals t.id into t_trader
                                    from tt in t_trader.DefaultIfEmpty()
                                    join s in dc.TB_Stock on m.id equals s.material
                                    join d2 in (dc.TB_Depot.Where(predicate1)) on s.depot equals d2.id into t_stockDepot
                                    from dd2 in t_stockDepot.DefaultIfEmpty()
                                    join c in dc.TB_Options on m.category equals c.id into t_category
                                    from cc in t_category.DefaultIfEmpty()
                                    select new QMaterial()
                                    {
                                        Id = m.id,
                                        Code = m.code,
                                        CnName = m.cnName,
                                        Specs = m.specs,
                                        StockId = s.id,
                                        StockDepotName = dd2.name,
                                        CurrentStockNum = s.num,
                                        DepotArea = s.area,
                                        BatchNo = s.batchNo,
                                        Expire = m.expire,
                                        DepartmentCode = dd1.code,
                                        DepartmentName = dd1.name,
                                        Brand = m.brand,
                                        Unusable = m.unusable,
                                        Unit = m.unit,
                                        ProviderCode = tt.code,
                                        ProviderName = tt.name,
                                        Source = m.source,
                                        PrjtId = m.projectId,
                                        PrjtCode = m.projectCode,
                                        CategoryName = cc.name
                                    };
                        return query;
                    }
                    else
                    {
                        var query = from m in (dc.TB_Material.Where(predicate))
                                    join d1 in dc.TB_Department on m.department equals d1.id into t_department
                                    from dd1 in t_department.DefaultIfEmpty()
                                    join t in dc.TB_Trader on m.provider equals t.id into t_trader
                                    from tt in t_trader.DefaultIfEmpty()
                                    join s in dc.TB_Stock on m.id equals s.material
                                    join d2 in (dc.TB_Depot.Where(predicate1)) on s.depot equals d2.id
                                    join c in dc.TB_Options on m.category equals c.id into t_category
                                    from cc in t_category.DefaultIfEmpty()
                                    select new QMaterial()
                                    {
                                        Id = m.id,
                                        Code = m.code,
                                        CnName = m.cnName,
                                        Specs = m.specs,
                                        StockId = s.id,
                                        StockDepotName = d2.name,
                                        CurrentStockNum = s.num,
                                        DepotArea = s.area,
                                        BatchNo = s.batchNo,
                                        Expire = m.expire,
                                        DepartmentCode = dd1.code,
                                        DepartmentName = dd1.name,
                                        Brand = m.brand,
                                        Unusable = m.unusable,
                                        Unit = m.unit,
                                        ProviderCode = tt.code,
                                        ProviderName = tt.name,
                                        Source = m.source,
                                        PrjtId = m.projectId,
                                        PrjtCode = m.projectCode,
                                        CategoryName = cc.name
                                    };
                        return query;
                    }
                }
                else
                {
                    var query = from m in (dc.TB_Material.Where(predicate))
                                join d1 in dc.TB_Department on m.department equals d1.id into t_department
                                from dd1 in t_department.DefaultIfEmpty()
                                join t in dc.TB_Trader on m.provider equals t.id into t_trader
                                from tt in t_trader.DefaultIfEmpty()
                                join c in dc.TB_Options on m.category equals c.id into t_category
                                from cc in t_category.DefaultIfEmpty()
                                //join s in dc.TB_Stock on m.id equals s.material
                                //join d2 in (dc.TB_Depot.Where(predicate1)) on s.depot equals d2.id
                                select new QMaterial()
                                {
                                    Id = m.id,
                                    Code = m.code,
                                    CnName = m.cnName,
                                    Specs = m.specs,
                                    StockId = null,
                                    StockDepotName = string.Empty,
                                    CurrentStockNum = null,
                                    DepotArea = string.Empty,
                                    BatchNo = string.Empty,
                                    Expire = m.expire,
                                    DepartmentCode = dd1.code,
                                    DepartmentName = dd1.name,
                                    Brand = m.brand,
                                    Unusable = m.unusable,
                                    Unit = m.unit,
                                    ProviderCode = tt.code,
                                    ProviderName = tt.name,
                                    Source = m.source,
                                    PrjtId = m.projectId,
                                    PrjtCode = m.projectCode,
                                    CategoryName = cc.name
                                };
                    return query;
                }
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增物料
        /// </summary>
        /// <param name="option">物料</param>
        /// <returns>新建物料系统编号</returns>        
        public int AddMaterial(TB_Material material)
        {
            try
            {
                dc.TB_Material.InsertOnSubmit(material);
                dc.SubmitChanges();
                return material.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新一个物料
        /// </summary>
        /// <param name="option">物料类</param>
        /// <returns>是否更新成功</returns>        
        public bool UpdateMaterial(TB_Material obj)
        {
            try
            {
                var o = dc.TB_Material.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string>{typeof(TB_Stock).Name,typeof(TB_ProjectElement).Name,typeof(TB_RecvDetail).Name,
                    typeof(TB_ReqDetail).Name,typeof(TB_ShippingDetail).Name,typeof(TB_TCDetail).Name,typeof(TB_ProductProject).Name,
                    typeof(TB_TRDetail).Name,typeof(TB_QCDetail).Name,typeof(TB_PrdnDetail).Name,typeof(TB_PrdnMaterial).Name,typeof(TB_RqrtDetail).Name,
                    typeof(TB_OrderDetail).Name,typeof(TB_ProductProject).Name});
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除一个物料
        /// </summary>
        /// <param name="id">物料系统编号</param>
        /// <returns>是否删除成功</returns>        
        public bool DeleteMaterial(int id)
        {
            try
            {
                var data = dc.TB_Material.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    //dc.TB_Material.DeleteOnSubmit(data);
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 存储过程检查物料删除
        /// </summary>
        /// <param name="id">物料Id</param>
        /// <returns>SPResult</returns>        
        public SPResult SPDeleteMaterial(int id)
        {
            SPResult spr = new SPResult();
            try
            {
                bool? ok = false;
                string msg = string.Empty;
                dc.SP_DeleteMateial(id, ref ok, ref msg);
                spr.Ok = Convert.ToBoolean(ok);
                spr.Msg = msg;
            }
            catch (Exception ex)
            {
                spr.Ok = false;
                spr.Msg = ex.Message;
            }
            return spr;
        }
        #endregion

        #region 仓库管理

        /// <summary>
        /// 获取单个仓库
        /// </summary>
        /// <param name="id">仓库系统编号</param>
        /// <returns>仓库对象</returns>
        public TB_Depot GetDepot(int id)
        { return dc.TB_Depot.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 查找仓库
        /// </summary>
        /// <param name="code">代号</param>
        /// <param name="name">名称</param>
        /// <param name="type">分类</param>
        /// <returns>仓库对象序列</returns>        
        public IEnumerable<TB_Depot> FindDepots(string code, string name, int? type)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Depot>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (type != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(type.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.仓库分类.ToString(), Convert.ToInt32(type));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate = predicate.And(p => ary.Contains(p.type.ToString()));
                }
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                if (!string.IsNullOrEmpty(name))
                    predicate = predicate.And(p => p.name.Contains(name));

                return dc.TB_Depot.Where(predicate);
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增仓库
        /// </summary>
        /// <param name="depot">仓库</param>
        /// <returns>新建仓库系统编号</returns>
        public int AddDepot(TB_Depot depot)
        {
            try
            {
                dc.TB_Depot.InsertOnSubmit(depot);
                dc.SubmitChanges();
                return depot.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新一个仓库
        /// </summary>
        /// <param name="option">仓库类</param>
        /// <returns>是否更新成功</returns>
        public bool UpdateDepot(TB_Depot depot)
        {
            try
            {
                var o = dc.TB_Depot.SingleOrDefault(d => d.id == depot.id);
                if (o != null)
                {
                    Common.objEval(depot, o, new List<string> { typeof(TB_ShippingDetail).Name, typeof(TB_Stock).Name, typeof(TB_TCDetail).Name, typeof(TB_TRDetail).Name });
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除一个仓库
        /// </summary>
        /// <param name="id">仓库系统编号</param>
        /// <returns>是否删除成功</returns>
        public bool DeleteDepot(int id)
        {
            try
            {
                var data = dc.TB_Depot.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 质检结果管理

        /// <summary>
        /// 获取单个质检结果
        /// </summary>
        /// <param name="id">质检结果系统编号</param>
        /// <returns>质检结果对象</returns>        
        public TB_QCResult GetQCResult(int id)
        { return dc.TB_QCResult.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 查找质检结果
        /// </summary>
        /// <returns>仓库对象序列</returns>
        public IEnumerable<TB_QCResult> FindQCResults()
        { return (from c in dc.TB_QCResult where !c.deleteFlag orderby c.id select c); }

        /// <summary>
        /// 新增质检结果
        /// </summary>
        /// <param name="obj">质检结果</param>
        /// <returns>新建质检结果系统编号</returns>
        public int AddQCResult(TB_QCResult obj)
        {
            try
            {
                dc.TB_QCResult.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新一个质检结果
        /// </summary>
        /// <param name="obj">质检结果类</param>
        /// <returns>是否更新成功</returns>
        public bool UpdateQCResult(TB_QCResult obj)
        {
            try
            {
                var o = dc.TB_QCResult.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_QCDetail).Name });
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }


        /// <summary>
        /// 删除一个质检结果
        /// </summary>
        /// <param name="id">质检结果系统编号</param>
        /// <returns>是否删除成功</returns>        
        public bool DeleteQCResult(int id)
        {
            try
            {
                var data = dc.TB_QCResult.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 质检问题类型管理

        /// <summary>
        /// 获取单个质检问题类型
        /// </summary>
        /// <param name="id">质检问题类型系统编号</param>
        /// <returns>质检问题类型对象</returns>
        public TB_QCProblemType GetQCProblemType(int id)
        { return dc.TB_QCProblemType.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 查找质检问题类型
        /// </summary>
        /// <returns>质检问题类型序列</returns>
        public IEnumerable<TB_QCProblemType> FindQCProblemTypes()
        { return (from c in dc.TB_QCProblemType where !c.deleteFlag orderby c.id select c); }

        /// <summary>
        /// 新增质检问题类型
        /// </summary>
        /// <param name="obj">质检问题类型</param>
        /// <returns>新建质检问题类型系统编号</returns>
        public int AddQCProblemType(TB_QCProblemType obj)
        {
            try
            {
                dc.TB_QCProblemType.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新一个质检问题类型
        /// </summary>
        /// <param name="obj">质检问题类型类</param>
        /// <returns>是否更新成功</returns>
        public bool UpdateQCProblemType(TB_QCProblemType obj)
        {
            try
            {
                var o = dc.TB_QCProblemType.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_QCProblem).Name });
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }


        /// <summary>
        /// 删除一个质检问题类型
        /// </summary>
        /// <param name="id">质检问题类型系统编号</param>
        /// <returns>是否删除成功</returns>
        public bool DeleteQCProblemType(int id)
        {
            try
            {
                var data = dc.TB_QCProblemType.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 工序管理
        /// <summary>
        /// 获取单个工序信息
        /// </summary>
        /// <param name="id">工序系统编号</param>
        /// <returns>工序类型</returns>
        public TB_Workstage GetWorkstage(int id)
        { return dc.TB_Workstage.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取工序关系树
        /// </summary>
        /// <returns></returns>
        public IEnumerable<WorkstageTreeNode> GetWorkstageTree()
        {
            var query = from g in dc.TB_Workstage
                        where !g.deleteFlag
                        select new WorkstageTreeNode()
                        {
                            Id = g.id,
                            Code = g.code,
                            Name = g.name,
                            ParentId = g.parentId
                        };
            return query;
        }

        /// <summary>
        /// 搜索工序
        /// </summary>
        /// <param name="parentId">上级工序</param>
        /// <returns>工序序列</returns>        
        public IEnumerable<TB_Workstage> FindWorkstage(int? parentId)
        {
            var predicate = PredicateBuilder.True<TB_Workstage>();
            predicate = predicate.And(p => !p.deleteFlag);
            if (parentId != null)
            { predicate = predicate.And(p => p.parentId == parentId); }
            return dc.TB_Workstage.Where(predicate);
        }

        /// <summary>
        /// 新增工序
        /// </summary>
        /// <param name="obj">工序类型</param>
        /// <returns>新增工序系统编号</returns>
        public int AddWorkstage(TB_Workstage obj)
        {
            try
            {
                dc.TB_Workstage.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新工序
        /// </summary>
        /// <param name="obj">工序类型</param>
        /// <returns>更新是否成功</returns>
        public bool UpdateWorkstage(TB_Workstage obj)
        {
            try
            {
                var o = dc.TB_Workstage.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_ProjectWorkstage).Name });
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除工序
        /// </summary>
        /// <param name="id">工序系统编号</param>
        /// <returns>删除是否成功</returns>        
        public bool DeleteWorkstage(int id)
        {
            try
            {
                var data = dc.TB_Workstage.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 部门管理
        /// <summary>
        /// 获取单个部门信息
        /// </summary>
        /// <param name="id">部门系统编号</param>
        /// <returns>部门类型</returns>
        public TB_Department GetDepartment(int id)
        {
            return dc.TB_Department.SingleOrDefault(d => d.id == id && !d.deleteFlag);
        }

        /// <summary>
        /// 搜索部门
        /// </summary>
        /// <param name="parentId">上级部门</param>
        /// <param name="code">部门代号</param>
        /// <param name="name">部门名称</param>
        /// <returns>部门序列</returns>
        public IEnumerable<TB_Department> FindDepartments(int? parentId,string code,string name)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Department>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (parentId != null)
                    predicate = predicate.And(p => p.parentId == parentId);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));
                if (!string.IsNullOrEmpty(name))
                    predicate = predicate.And(p => p.name.Contains(name));
                return dc.TB_Department.Where(predicate);
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增部门
        /// </summary>
        /// <param name="obj">部门类型</param>
        /// <returns>新增部门系统编号</returns>
        public int AddDepartment(TB_Department obj)
        {
            try
            {
                dc.TB_Department.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新部门
        /// </summary>
        /// <param name="obj">部门类型</param>
        /// <returns>更新是否成功</returns>
        public bool UpdateDepartment(TB_Department obj)
        {
            try
            {
                var o = dc.TB_Department.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o);
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除部门
        /// </summary>
        /// <param name="id">部门系统编号</param>
        /// <returns>删除是否成功</returns>
        public bool DeleteDepartment(int id)
        {
            try
            {
                var data = dc.TB_Department.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 用户管理
        /// <summary>
        /// 获取单个用户信息
        /// </summary>
        /// <param name="id">用户系统编号</param>
        /// <returns>用户类型</returns>
        public TB_User GetUser(int id)
        { return dc.TB_User.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="code"></param>
        /// <param name="pwd"></param>
        /// <returns>LoginResult</returns>        
        public LoginResult CheckLogin(string code, string pwd)
        {
            LoginResult lr = new LoginResult();
            try
            {
                var predicate = PredicateBuilder.True<TB_User>();
                predicate = predicate.And(p => !p.deleteFlag && p.code == code);

                var query = from u in dc.TB_User.Where(predicate)
                            join d in dc.TB_Department on u.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XUser()
                            {
                                User = u,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name
                            };

                XUser user = (query).SingleOrDefault();
                if (user != null)
                {
                    string encryptPwd = string.Empty;
                    if (pwd != string.Empty)
                        encryptPwd = BZSC.Common.EncryptCommon.MD5Encrypt(pwd);
                    if ((string.IsNullOrEmpty(user.User.pwd) && string.IsNullOrEmpty(encryptPwd)) || (user.User.pwd != null && user.User.pwd.Equals(encryptPwd)))
                    {
                        lr.User = user;
                        lr.ErrorMsg = string.Empty;
                    }
                    else
                        lr.ErrorMsg = "用户密码错误";

                }
                else
                    lr.ErrorMsg = "查无此用户信息！";
            }
            catch (Exception ex)
            {
                lr.ErrorMsg = ex.Message;
            }
            return lr;
        }

        /// <summary>
        /// 根据用户代号获取带关联的用户
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public XUser GetLoginUser(string code)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_User>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.code == code);

                var query = from u in dc.TB_User.Where(predicate)
                            join d in dc.TB_Department on u.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XUser()
                            {
                                User = u,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name
                            };
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="department">用户所属部门</param>
        /// <param name="code">用户代号</param>
        /// <param name="name">用户名称</param>
        /// <returns></returns>
        public IEnumerable<XUser> FindUsers(int? department, string code, string name)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_User>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (department != null)
                    predicate = predicate.And(p => p.department == department);

                if (!string.IsNullOrEmpty(name))
                    predicate = predicate.And(p => p.name.Contains(name));

                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var query = from u in dc.TB_User.Where(predicate)
                            join d in dc.TB_Department on u.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XUser()
                            {
                                User = u,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="obj">用户类型</param>
        /// <returns>新增用户系统编号</returns>
        public int AddUser(TB_User obj)
        {
            try
            {
                dc.TB_User.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="obj">用户类型</param>
        /// <returns>更新是否成功</returns>
        public bool UpdateUser(TB_User obj)
        {
            try
            {
                var o = dc.TB_User.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o);
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户系统编号</param>
        /// <returns>删除是否成功</returns>
        public bool DeleteUser(int id)
        {
            try
            {
                var data = dc.TB_User.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }
        #endregion

        #region 获取流水号
        /// <summary>
        /// 获取流水号（单据、分类）
        /// </summary>
        /// <param name="type">1-单据,2-分类</param>
        /// <param name="billType">单据类型</param>
        /// <param name="len">自定义流水号长度</param>
        /// <param name="prefix">是否加前缀</param>
        /// <param name="fillZero">是否补零</param>
        /// <returns>流水号</returns>        
        public string GetSerialNo(int type, string billType, int len, bool prefix, bool fillZero, bool fillDate)
        {
            string code = string.Empty;
            try
            {
                dc.GetNewBillNo(type, billType, len, prefix, fillZero, fillDate, ref code);
            }
            catch { }
            return code;
        }
        #endregion

        #endregion

        #region 进销存部分

        #region 收发货管理

        /// <summary>
        /// 获取单个收发货单数据
        /// </summary>
        /// <param name="id">系统编码</param>
        /// <returns>Shipping</returns>
        public TB_Shipping GetShipping(int id)
        { return dc.TB_Shipping.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取单个收发货单数据
        /// </summary>
        /// <param name="id">系统编码</param>
        /// <returns>GRWL.BZSC.Common.XShipping</returns>
        public XShipping GetXShipping(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Shipping>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from s in (dc.TB_Shipping.Where(predicate))
                            join u1 in dc.TB_User on s.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on s.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on s.businessman equals u3.id into t_businessman
                            from uu3 in t_businessman.DefaultIfEmpty()
                            join u4 in dc.TB_User on s.mender equals u4.id into t_mender
                            from uu4 in t_mender.DefaultIfEmpty()
                            join t in dc.TB_Trader on s.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XShipping()
                            {
                                Shipping = s,
                                OperatorCode = uu1.code,
                                OperatorName = uu1.name,
                                AssessorCode = uu2.code,
                                AssessorName = uu2.name,
                                TraderCode = tt.code,
                                TraderName = tt.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                BusinessCode = uu3.code,
                                BusinessName = uu3.name,
                                MenderCode = uu4.code,
                                MenderName = uu4.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索收发货单
        /// </summary>
        /// <param name="type">单据类型</param>
        /// <param name="code">单据代号</param>
        /// <param name="operatorName">制单人名称</param>
        /// <param name="status">单据状态</param>
        /// <param name="sDate">制单开始时间</param>
        /// <param name="eDate">制单结束时间</param>
        /// <param name="traderName">往来单位名称</param>
        /// <param name="materailCode">物料代号</param>
        /// <param name="materialCategory">物料分类</param>
        /// <param name="materialName">物料名称</param>
        /// <returns>收发货单序列</returns>        
        public IEnumerable<QShipping> FindShippings(string type, string code, string operatorName, string status, DateTime? sDate, DateTime? eDate,
            int? trader, string materailCode, int? materialCategory, string materialName)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Shipping>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(type))
                    predicate = predicate.And(p => p.type == type);
                if (trader != null)
                    predicate = predicate.And(p => p.trader == trader);
                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.shippingDate >= sDate);
                    predicate = predicate.And(p => p.shippingDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate1 = PredicateBuilder.True<TB_Trader>();
                predicate1 = predicate1.And(p => !p.deleteFlag);

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (materialCategory != null)
                    predicate2 = predicate2.And(p => p.category == materialCategory);
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materailCode));
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Options>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (materialCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(materialCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(materialCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.id.ToString()));
                }

                var query = from s in (dc.TB_Shipping.Where(predicate))
                            join a in dc.TB_ShippingDetail on s.id equals a.shipping
                            join m in (dc.TB_Material.Where(predicate2)) on a.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join c in (dc.TB_Options.Where(predicate3)) on mm.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join t in (dc.TB_Trader.Where(predicate1)) on s.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assesor
                            from uu1 in t_assesor.DefaultIfEmpty()
                            select new QShipping()
                            {
                                Id = s.id,
                                Code = s.code,
                                //OrderId = a.order,
                                OrderCode = a.orderCode,
                                ShippingDate = s.shippingDate,
                                //Trader = s.trader,
                                TraderCode = tt.code,
                                TraderName = tt.name,
                                //MaterialId = mm.id,
                                MaterialCode = mm.code,
                                MaterialName = mm.cnName,
                                MaterialSpecs = mm.specs,
                                ShippingNum = a.shippingNum,
                                Address = s.address,
                                //OperatorId = s.@operator,
                                OperatorName = uu.name,
                                //AssessorId = s.assessor,
                                AssessorName = uu1.name,
                                //CategoryId = mm.category,
                                CategoryName = cc.name,
                                Memo = s.memo,
                                DetailMemo = a.memo,
                                Status = s.status,
                                Unit = mm.unit,
                                PrevCode = a.prevCode
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增收发货单
        /// </summary>
        /// <param name="obj">收发货单</param>
        /// <returns>新增收发货单系统编号</returns>        
        public int AddShipping(TB_Shipping obj)
        {
            try
            {
                dc.TB_Shipping.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新收发货单
        /// </summary>
        /// <param name="obj">收发货单</param>
        /// <returns>更新是否成功</returns>
        public bool UpdateShipping(TB_Shipping obj, bool updateSubs)
        {
            //try
            //{
            //    var o = dc.TB_Shipping.SingleOrDefault(d => d.id == shipping.id);
            //    if (o != null)
            //    {
            //        //shipping.TB_Trader = dc.TB_Trader.SingleOrDefault(t => t.id == shipping.trader);//外键指向
            //        Common.objEval(shipping, o, new List<string> { typeof(TB_ShippingDetail).Name, typeof(TB_Trader).Name });
            //        bool ok = false;
            //        if (shippingDetails != null)
            //        {
            //            var sds = from d in dc.TB_ShippingDetail where d.shipping == shipping.id select d;
            //            dc.TB_ShippingDetail.DeleteAllOnSubmit(sds);
            //            dc.TB_ShippingDetail.InsertAllOnSubmit(shippingDetails);
            //        }

            //        dc.SubmitChanges();
            //        return ok;
            //    }
            //}
            //catch { }
            //return false;
            try
            {
                var o = dc.TB_Shipping.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_ShippingDetail).Name, typeof(TB_Trader).Name });

                    if (updateSubs)
                    {
                        //清除原明细数据
                        dc.TB_ShippingDetail.DeleteAllOnSubmit(o.TB_ShippingDetail);

                        foreach (TB_ShippingDetail qcd in obj.TB_ShippingDetail)
                        {
                            TB_ShippingDetail nQcd = new TB_ShippingDetail();
                            Common.objEval(qcd, nQcd, new List<string> { typeof(TB_Depot).Name, typeof(TB_Material).Name, typeof(TB_Order).Name, typeof(TB_Shipping).Name });
                            o.TB_ShippingDetail.Add(nQcd);
                        }
                    }
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除收发货单
        /// </summary>
        /// <param name="id">收发货单系统编号</param>
        /// <returns>删除是否成功</returns>
        public bool DeleteShipping(int id)
        {
            try
            {
                var data = dc.TB_Shipping.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 收发货明细管理
        /// <summary>
        /// 获取单个收发货明细数据
        /// </summary>
        /// <param name="id">收发货明细系统编码</param>
        /// <returns>TB_ShippingDetail</returns>        
        public TB_ShippingDetail GetShippingDetail(int id)
        { return dc.TB_ShippingDetail.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取单个收发货明细数据
        /// </summary>
        /// <param name="id">收发货明细系统编码</param>
        /// <returns>XShippingDetail</returns>
        public XShippingDetial GetXShippingDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ShippingDetail>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from s in (dc.TB_ShippingDetail.Where(predicate))
                            join m in dc.TB_Material on s.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join d in dc.TB_Depot on s.depot equals d.id into t_depot
                            from dd in t_depot.DefaultIfEmpty()
                            select new XShippingDetial()
                            {
                                ShippingDetail = s,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                Expire = mm.expire,
                                DepotCode = dd.code,
                                DepotName = dd.name,
                                Unit = mm.unit
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据收发货单获取收发货明细
        /// </summary>
        /// <param name="id">收发货单系统编码</param>
        /// <returns>TB_ShippingDetail序列</returns>
        public IEnumerable<XShippingDetial> GetShippingDetails(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ShippingDetail>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.shipping == id);

                var query = from s in (dc.TB_ShippingDetail.Where(predicate))
                            join m in dc.TB_Material on s.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join d in dc.TB_Depot on s.depot equals d.id into t_depot
                            from dd in t_depot.DefaultIfEmpty()
                            select new XShippingDetial()
                            {
                                ShippingDetail = s,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                Expire = mm.expire,
                                DepotCode = dd.code,
                                DepotName = dd.name,
                                Unit = mm.unit
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增收发货明细
        /// </summary>
        /// <param name="obj">TB_ShippingDetail</param>
        /// <returns>新增收发货明细系统编号</returns>
        public int AddShippingDetail(TB_ShippingDetail obj)
        {
            try
            {
                dc.TB_ShippingDetail.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }
        #endregion

        #region 请购
        /// <summary>
        /// 获取单个请购单数据
        /// </summary>
        /// <param name="id">系统编码</param>
        /// <returns>TB_Requisition</returns>
        public TB_Requisition GetRequisition(int id)
        { return dc.TB_Requisition.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取单个带关联的请购单
        /// </summary>
        /// <param name="id">系统编码</param>
        /// <returns>XRequisition</returns>
        public XRequisition GetXRequisition(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Requisition>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_Requisition.Where(predicate))
                            join u1 in dc.TB_User on r.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on r.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on r.businessman equals u3.id into t_businessman
                            from uu3 in t_businessman.DefaultIfEmpty()
                            join u4 in dc.TB_User on r.mender equals u4.id into t_mender
                            from uu4 in t_mender.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XRequisition()
                            {
                                Requisition = r,
                                OperatorCode = uu1.code,
                                OperatorName = uu1.name,
                                AssessorCode = uu2.code,
                                AssessorName = uu2.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                BusinessCode = uu3.code,
                                BusinessName = uu3.name,
                                MenderCode = uu4.code,
                                MenderName = uu4.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜查请购单
        /// </summary>
        /// <param name="code">请购单号</param>
        /// <param name="operatorName">制单人名称</param>
        /// <param name="status">请购单状态</param>
        /// <param name="sDate">开始时间</param>
        /// <param name="eDate">结束时间</param>
        /// <param name="materailCode">物料代号</param>
        /// <param name="materialCategory">物料分类名</param>
        /// <param name="materialName">物料名称</param>
        /// <returns>QRequisition序列</returns>
        public IEnumerable<QRequisition> FindRequisitions(string code, string operatorName, string status, DateTime? sDate, DateTime? eDate, string materailCode, int? materialCategory, string materialName)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Requisition>();
                predicate = predicate.And(p => !p.deleteFlag);

                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.reqDate >= sDate);
                    predicate = predicate.And(p => p.reqDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (materialCategory != null)
                    predicate2 = predicate2.And(p => p.category == materialCategory);
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materailCode));
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Options>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (materialCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(materialCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(materialCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.id.ToString()));
                }

                var query = from s in (dc.TB_Requisition.Where(predicate))
                            join a in dc.TB_ReqDetail on s.id equals a.reqn
                            join m in (dc.TB_Material.Where(predicate2)) on a.material equals m.id
                            join c in (dc.TB_Options.Where(predicate3)) on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            join u2 in dc.TB_User on s.businessman equals u2.id into t_businessman
                            from uu2 in t_businessman.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join t in dc.TB_Trader on s.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            select new QRequisition()
                            {
                                Id = s.id,
                                Code = s.code,
                                ReqDate = s.reqDate,
                                //MaterialId = m.id,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Specs = m.specs,
                                CategoryCode = cc.code,
                                CategoryName = cc.name,
                                Num = a.num,
                                OperatorCode = uu.code,
                                OperatorName = uu.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                BusinessmanCode = uu2.code,
                                BusinessmanName = uu2.name,
                                AssessorCode = uu1.code,
                                AssessorName = uu1.name,
                                DetailMemo = a.memo,
                                Memo = s.memo,
                                Status = s.status,
                                IsVerify = s.isVerify,
                                TraderName = tt.name
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增请购单
        /// </summary>
        /// <param name="obj">请购单</param>
        /// <returns>新增请购单系统编号</returns>
        public int AddRequisition(TB_Requisition obj)
        {
            try
            {
                dc.TB_Requisition.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新请购单
        /// </summary>
        /// <param name="requisition">请购单类型</param>
        /// <param name="requisitionDetails">请购明细</param>
        /// <returns>更新是否成功</returns>
        public bool UpdateRequisition(TB_Requisition obj, bool updateSubs)
        {
            //try
            //{
            //    var o = dc.TB_Requisition.SingleOrDefault(d => d.id == obj.id);
            //    if (o != null)
            //    {
            //        Common.objEval(obj, o, new List<string> { typeof(TB_ReqDetail).Name });
            //        if (requisitionDetails != null)
            //        {
            //            var qcds = from d in dc.TB_ReqDetail where d.reqn == o.id select d;
            //            foreach (TB_ReqDetail qcd in qcds)//清除原明细数据
            //                o.TB_ReqDetail.Remove(qcd);

            //            foreach (TB_ReqDetail qcd in requisitionDetails)
            //                o.TB_ReqDetail.Add(qcd);
            //        }

            //        dc.SubmitChanges();
            //        return true;
            //    }
            //}
            //catch { }
            //return false;
            try
            {
                var o = dc.TB_Requisition.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_ReqDetail).Name });

                    if (updateSubs)
                    {
                        //清除原明细数据
                        dc.TB_ReqDetail.DeleteAllOnSubmit(o.TB_ReqDetail);

                        foreach (TB_ReqDetail qcd in obj.TB_ReqDetail)
                        {
                            TB_ReqDetail nQcd = new TB_ReqDetail();
                            Common.objEval(qcd, nQcd, new List<string> { typeof(TB_OrderDetail).Name, typeof(TB_Material).Name, typeof(TB_Requisition).Name });
                            o.TB_ReqDetail.Add(nQcd);
                        }
                    }
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除请购单
        /// </summary>
        /// <param name="id">请购单系统编号</param>
        /// <returns>删除是否成功</returns>
        public bool DeleteRequisition(int id)
        {
            try
            {
                var data = dc.TB_Requisition.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 请购明细
        /// <summary>
        /// 获取单个请购明细数据
        /// </summary>
        /// <param name="id">请购明细系统编码</param>
        /// <returns>TB_ReqDetail</returns>
        public TB_ReqDetail GetReqDetail(int id)
        { return dc.TB_ReqDetail.SingleOrDefault(d => d.id == id); }

        /// <summary>
        /// 获取单个带关联的请购明细
        /// </summary>
        /// <param name="id">请购明细系统编码</param>
        /// <returns>XReqDetial</returns>
        public XReqDetial GetXReqDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ReqDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_ReqDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            select new XReqDetial()
                            {
                                ReqDetial = r,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                Expire = mm.expire,
                                Unit = mm.unit
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据请购单获取请购明细
        /// </summary>
        /// <param name="id">请购单系统编码</param>
        /// <returns>TB_ReqDetail序列</returns>
        public IEnumerable<TB_ReqDetail> GetReqDetails(int id)
        {
            return (from s in dc.TB_ReqDetail where s.reqn == id select s);
        }

        /// <summary>
        /// 根据请购单获取带关联的请购明细
        /// </summary>
        /// <param name="id">请购单系统编码</param>
        /// <returns>XReqDetail序列</returns>
        public IEnumerable<XReqDetial> GetXReqDetails(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ReqDetail>();
                predicate = predicate.And(p => p.reqn == id);

                var query = from r in (dc.TB_ReqDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            select new XReqDetial()
                            {
                                ReqDetial = r,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                Expire = mm.expire,
                                Unit = mm.unit
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增请购明细
        /// </summary>
        /// <param name="obj">TB_ReqDetail</param>
        /// <returns>新增请购明细系统编号</returns>        
        public int AddReqDetail(TB_ReqDetail obj)
        {
            try
            {
                dc.TB_ReqDetail.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }
        #endregion

        #region 质检单
        /// <summary>
        /// 获取一个带关联的质检单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XQC GetXQC(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QC>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from q in (dc.TB_QC.Where(predicate))
                            join u1 in dc.TB_User on q.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on q.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join t in dc.TB_Trader on q.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            select new XQC()
                            {
                                QC = q,
                                OperatorName = uu1.name,
                                AssessorName = uu2.name,
                                TraderCode = tt.code,
                                TraderName = tt.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索质检单
        /// </summary>
        /// <param name="type"></param>
        /// <param name="code"></param>
        /// <param name="operatorName"></param>
        /// <param name="status"></param>
        /// <param name="sDate"></param>
        /// <param name="eDate"></param>
        /// <returns></returns>
        public IEnumerable<QQC> FindQCs(string type, string code, string operatorName, string status, DateTime? sDate, DateTime? eDate)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QC>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(type))
                    predicate = predicate.And(p => p.type == type);
                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.qcDate >= sDate);
                    predicate = predicate.And(p => p.qcDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var query = from s in (dc.TB_QC.Where(predicate))
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            join t in dc.TB_Trader on s.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            join d in dc.TB_QCDetail on s.id equals d.qc
                            join m in dc.TB_Material on d.material equals m.id
                            select new QQC()
                            {
                                Id = s.id,
                                Code = s.code,
                                QCDate = s.qcDate,
                                OperatorName = uu.name,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Type = s.type,
                                TraderName = tt.name,
                                IsVerify = s.isVerify,
                                AssessorName = uu1.name,
                                Memo = s.memo,
                                Status = s.status,
                                PrevId = d.prevId,
                                PrevCode = d.prevCode,
                                PrevType = d.prevType,
                                DetailMemo = d.memo,
                                Specs = d.specs,
                                CheckNum = d.checkNum,
                                DeliveryNum = d.deliveryNum
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增质检单
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddQC(TB_QC obj)
        {
            try
            {
                dc.TB_QC.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新质检单
        /// </summary>
        /// <param name="?"></param>
        /// <param name="qcDetails"></param>
        /// <param name="qcProblems"></param>
        /// <returns></returns>        
        public bool UpdateQC(TB_QC obj)
        {
            try
            {
                var o = dc.TB_QC.SingleOrDefault(d => d.id == obj.id);
                Common.objEval(obj, o, new List<string> { typeof(TB_QCDetail).Name, typeof(TB_Trader).Name });
                bool ok = false;
                if (o != null)
                {
                    var qcds = from d in dc.TB_QCDetail where d.qc == o.id select d;
                    foreach (TB_QCDetail qcd in o.TB_QCDetail)//清除原明细数据
                        qcd.TB_QCProblem.Clear();
                    //o.TB_QCDetail.Clear();                    
                    dc.TB_QCDetail.DeleteAllOnSubmit(o.TB_QCDetail);

                    foreach (TB_QCDetail qcd in obj.TB_QCDetail)//更新明细数据
                    {
                        TB_QCDetail nQcd = new TB_QCDetail();
                        Common.objEval(qcd, nQcd, new List<string> { typeof(TB_Material).Name, typeof(TB_QC).Name, typeof(TB_QCProblem).Name, typeof(TB_QCResult).Name, typeof(TB_ShippingDetail).Name, typeof(TB_TRDetail).Name });
                        foreach (TB_QCProblem qcp in qcd.TB_QCProblem)
                        {
                            TB_QCProblem nQcp = new TB_QCProblem();
                            Common.objEval(qcp, nQcp, new List<string> { typeof(TB_QCDetail).Name, typeof(TB_QCProblemType).Name });
                            nQcd.TB_QCProblem.Add(nQcp);
                        }
                        o.TB_QCDetail.Add(nQcd);
                    }
                }
                dc.SubmitChanges();
                return ok;
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除质检单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteQC(int id)
        {
            try
            {
                var data = dc.TB_QC.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }
        #endregion

        #region 质检单明细
        /// <summary>
        /// 获取单个带关联的质检明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XQCDetail GetXQCDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QCDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from q in (dc.TB_QCDetail.Where(predicate))
                            join r in dc.TB_QCResult on q.qcResult equals r.id into t_qcResult
                            from rr in t_qcResult.DefaultIfEmpty()
                            join u in dc.TB_User on q.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join m in dc.TB_Material on q.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            select new XQCDetail()
                            {
                                QCDetail = q,
                                MaterialName = mm.cnName,
                                OperatorName = uu.name,
                                QCResultName = rr.result,
                                Unit = mm.unit
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据质检单id获取带关联的质检明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<XQCDetail> GetXQCDetials(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QCDetail>();
                predicate = predicate.And(p => p.qc == id);

                var query = from q in (dc.TB_QCDetail.Where(predicate))
                            join r in dc.TB_QCResult on q.qcResult equals r.id into t_qcResult
                            from rr in t_qcResult.DefaultIfEmpty()
                            join u in dc.TB_User on q.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join m in dc.TB_Material on q.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            select new XQCDetail()
                            {
                                QCDetail = q,
                                MaterialName = mm.cnName,
                                OperatorName = uu.name,
                                QCResultName = rr.result,
                                Unit = mm.unit
                            };
                return query;

            }
            catch { }
            return null;
        }

        ///// <summary>
        ///// 新增质检明细
        ///// </summary>
        ///// <param name="obj"></param>
        ///// <param name="qcProblems"></param>
        ///// <returns></returns>
        //public int AddQCDetial(TB_QCDetail obj, IEnumerable<TB_QCProblem> qcProblems)
        //{
        //    try
        //    {
        //        if (qcProblems != null)
        //        {
        //            foreach (TB_QCProblem qcp in qcProblems)
        //                obj.TB_QCProblem.Add(qcp);
        //        }
        //        dc.TB_QCDetail.InsertOnSubmit(obj);
        //        dc.SubmitChanges();
        //        return obj.id;
        //    }
        //    catch { }
        //    return 0;
        //}
        #endregion

        #region 质检问题明细
        /// <summary>
        /// 获取单个带关联的质检问题明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XQCProblem GetXQCProblem(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QCProblem>();
                predicate = predicate.And(p => p.id == id);

                var query = from q in (dc.TB_QCProblem.Where(predicate))
                            join p in dc.TB_QCProblemType on q.qcProblemType equals p.id into t_qcProblemType
                            from pp in t_qcProblemType.DefaultIfEmpty()
                            select new XQCProblem()
                            {
                                QCProblem = q,
                                ProblemName = pp.name,
                                IsScrap = pp.isScrap
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据质检单明细id获取带关联的质检问题明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<XQCProblem> GetXQCProblems(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QCProblem>();
                predicate = predicate.And(p => p.qcDetail == id);

                var query = from q in (dc.TB_QCProblem.Where(predicate))
                            join p in dc.TB_QCProblemType on q.qcProblemType equals p.id into t_qcProblemType
                            from pp in t_qcProblemType.DefaultIfEmpty()
                            select new XQCProblem()
                            {
                                QCProblem = q,
                                ProblemName = pp.name,
                                IsScrap = pp.isScrap
                            };
                return query;

            }
            catch { }
            return null;
        }

        ///// <summary>
        ///// 新增质检问题明细
        ///// </summary>
        ///// <param name="obj"></param>
        ///// <returns></returns>
        //public int AddQCProblem(TB_QCProblem obj)
        //{
        //    try
        //    {
        //        dc.TB_QCProblem.InsertOnSubmit(obj);
        //        dc.SubmitChanges();
        //        return obj.id;
        //    }
        //    catch { }
        //    return 0;
        //}
        #endregion

        #region 报价单
        /// <summary>
        /// 获取一个带关联的报价单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XQuotation GetXQuotation(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Quotation>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from q in (dc.TB_Quotation.Where(predicate))
                            join u1 in dc.TB_User on q.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on q.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on q.businessman equals u3.id into t_bussiness
                            from uu3 in t_bussiness.DefaultIfEmpty()
                            join u4 in dc.TB_User on q.mender equals u4.id into t_mender
                            from uu4 in t_mender.DefaultIfEmpty()
                            join t in dc.TB_Trader on q.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            join d in dc.TB_Department on q.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join o in dc.TB_Options on q.tax equals o.id into t_tax
                            from oo in t_tax.DefaultIfEmpty()
                            select new XQuotation()
                            {
                                Quotation = q,
                                OperatorName = uu1.name,
                                AssessorName = uu2.name,
                                TraderCode = tt.code,
                                TraderName = tt.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                BusinessCode = uu3.code,
                                BusinessName = uu3.name,
                                TaxCode = oo.code,
                                TaxName = oo.name,
                                MenderName = uu4.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜查带关联的报价单
        /// </summary>
        /// <param name="code">报价单号</param>
        /// <param name="operatorName">制单人名称</param>
        /// <param name="status">请购单状态</param>
        /// <param name="sDate">开始时间</param>
        /// <param name="eDate">结束时间</param>
        /// <param name="materailCode">物料代号</param>
        /// <param name="materialCategory">物料分类名</param>
        /// <param name="materialName">物料名称</param>
        /// <returns></returns>
        public IEnumerable<QQuotation> FindQuotations(string code, string operatorName, string status, DateTime? sDate, DateTime? eDate, string materailCode, int? materialCategory, string materialName)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Quotation>();
                predicate = predicate.And(p => !p.deleteFlag);

                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.quoteDate >= sDate);
                    predicate = predicate.And(p => p.quoteDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (materialCategory != null)
                    predicate2 = predicate2.And(p => p.category == materialCategory);
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materailCode));
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Options>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (materialCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(materialCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(materialCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.id.ToString()));
                }

                var query = from s in (dc.TB_Quotation.Where(predicate))
                            join a in dc.TB_QuoteDetail on s.id equals a.qttn
                            join m in (dc.TB_Material.Where(predicate2)) on a.material equals m.id
                            join c in (dc.TB_Options.Where(predicate3)) on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            join u2 in dc.TB_User on s.businessman equals u2.id into t_businessman
                            from uu2 in t_businessman.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join t in dc.TB_Trader on s.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            select new QQuotation()
                            {
                                Id = s.id,
                                Code = s.code,
                                TraderName = tt.name,
                                DepartmentName = dd.name,
                                BusinessName = uu2.name,
                                MaterialCode = a.materialCode,
                                MaterialName = m.cnName,
                                Price = a.price,
                                TaxPrice = a.taxPrice,
                                TaxRate = a.taxRate,
                                TraderMtrlModel = a.traderMtrlModel,
                                TraderMtrlName = a.traderMtrlName,
                                Amount = a.amount,
                                TaxAmount = a.taxAmount,
                                Specs = m.specs,
                                Unit = a.unit,
                                Expire = m.expire,
                                Status = s.status,
                                OperatorName = uu.name,
                                QuoteDate = s.quoteDate,
                                IsVerify = s.isVerify
                            };
                return query;

            }
            catch { }
            return null;
        }


        /// <summary>
        /// 新增报价单
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddQuotation(TB_Quotation obj)
        {
            try
            {
                dc.TB_Quotation.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新报价单
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="details"></param>
        /// <returns></returns>
        public bool UpdateQuotation(TB_Quotation obj, bool updateSubs)
        {
            //try
            //{
            //    var o = dc.TB_Quotation.SingleOrDefault(d => d.id == obj.id);
            //    if (o != null)
            //    {
            //        Common.objEval(obj, o, new List<string> { typeof(TB_QuoteDetail).Name, typeof(TB_Trader).Name });
            //        if (details != null)
            //        {
            //            var dts = from d in dc.TB_QuoteDetail where d.qttn == o.id select d;
            //            foreach (TB_QuoteDetail dt in dts)//清除原明细数据
            //                o.TB_QuoteDetail.Remove(dt);

            //            foreach (TB_QuoteDetail dt in details)
            //                o.TB_QuoteDetail.Add(dt);
            //        }

            //        dc.SubmitChanges();
            //        return true;
            //    }
            //}
            //catch { }
            //return false;
            try
            {
                var o = dc.TB_Quotation.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_QuoteDetail).Name, typeof(TB_Trader).Name });

                    if (updateSubs)
                    {
                        //清除原明细数据
                        dc.TB_QuoteDetail.DeleteAllOnSubmit(o.TB_QuoteDetail);

                        foreach (TB_QuoteDetail qcd in obj.TB_QuoteDetail)
                        {
                            TB_QuoteDetail nQcd = new TB_QuoteDetail();
                            Common.objEval(qcd, nQcd, new List<string> { typeof(TB_Quotation).Name });
                            o.TB_QuoteDetail.Add(nQcd);
                        }
                    }
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除报价单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteQuotation(int id)
        {
            try
            {
                var data = dc.TB_Quotation.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }
        #endregion

        #region 报价单明细
        /// <summary>
        /// 获取单个带关联的报价明细
        /// </summary>
        /// <param name="id">报价明细系统编码</param>
        /// <returns>XQuoteDetial</returns>
        public XQuoteDetial GetXQuoteDetial(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QuoteDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_QuoteDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join c in dc.TB_Options on mm.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            select new XQuoteDetial()
                            {
                                QuoteDetail = r,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                Unit = r.unit,
                                Expire = mm.expire,
                                Brand = mm.brand,
                                CategoryName = cc.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据报价单获取带关联的报价明细
        /// </summary>
        /// <param name="id">报价单系统编码</param>
        /// <returns>XQuoteDetial序列</returns>
        public IEnumerable<XQuoteDetial> GetXQuoteDetials(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_QuoteDetail>();
                predicate = predicate.And(p => p.qttn == id);

                var query = from r in (dc.TB_QuoteDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join c in dc.TB_Options on mm.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            select new XQuoteDetial()
                            {
                                QuoteDetail = r,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                Unit = r.unit,
                                Expire = mm.expire,
                                Brand = mm.brand,
                                CategoryName = cc.name
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增报价明细
        /// </summary>
        /// <param name="obj">TB_ReqDetail</param>
        /// <returns>新增报价明细系统编号</returns>
        public int AddQuoteDetail(TB_QuoteDetail obj)
        {
            try
            {
                dc.TB_QuoteDetail.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }
        #endregion

        #region 订单
        /// <summary>
        /// 获取一个带关联的订单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XOrder GetXOrder(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Order>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from q in (dc.TB_Order.Where(predicate))
                            join u1 in dc.TB_User on q.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on q.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on q.businessman equals u3.id into t_bussiness
                            from uu3 in t_bussiness.DefaultIfEmpty()
                            join u4 in dc.TB_User on q.mender equals u4.id into t_mender
                            from uu4 in t_mender.DefaultIfEmpty()
                            join t in dc.TB_Trader on q.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            join d in dc.TB_Department on q.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XOrder()
                            {
                                Order = q,
                                TraderCode = tt.code,
                                TraderName = tt.name,
                                OperatorName = uu1.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                BusinessmanCode = uu3.code,
                                BusinessmanName = uu3.name,
                                AssessorName = uu2.name,
                                MenderName = uu4.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜查带关联的订单
        /// </summary>
        /// <param name="orderType">订单类型</param>
        /// <param name="code">订单号</param>
        /// <param name="operatorName">制单人名称</param>
        /// <param name="status">状态</param>
        /// <param name="sDate">开始时间</param>
        /// <param name="eDate">结束时间</param>
        /// <param name="materailCode">物料代号</param>
        /// <param name="materialCategory">物料分类名</param>
        /// <param name="materialName">物料名称</param>
        /// <param name="isMRP">是否已运行MRP需求</param>
        /// <param name="isProduce">是否转生产</param>
        /// <param name="isCheck">是否经过质检</param>
        /// <returns></returns>        
        public IEnumerable<QOrder> FindOrders(string orderType, string code, string operatorName, string status, DateTime? sDate, DateTime? eDate, string materailCode, int? materialCategory, string materialName, bool? isMRP, bool? isProduce, bool? isCheck)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Order>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (isMRP != null)
                    predicate = predicate.And(p => p.isMRP == isMRP);
                if (isProduce != null)
                    predicate = predicate.And(p => p.isProduce == isProduce);
                if (isCheck != null)
                    predicate = predicate.And(p => p.isCheck == isCheck);
                if (!string.IsNullOrEmpty(orderType))
                    predicate = predicate.And(p => p.orderType == orderType);
                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.orderDate >= sDate);
                    predicate = predicate.And(p => p.orderDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (materialCategory != null)
                    predicate2 = predicate2.And(p => p.category == materialCategory);
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materailCode));
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Options>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (materialCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(materialCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(materialCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.id.ToString()));
                }

                var query = from s in (dc.TB_Order.Where(predicate))
                            join a in dc.TB_OrderDetail on s.id equals a.orderId
                            join m in (dc.TB_Material.Where(predicate2)) on a.material equals m.id
                            join c in (dc.TB_Options.Where(predicate3)) on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            join u2 in dc.TB_User on s.businessman equals u2.id into t_businessman
                            from uu2 in t_businessman.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join t in dc.TB_Trader on s.trader equals t.id into t_trader
                            from tt in t_trader.DefaultIfEmpty()
                            select new QOrder()
                            {
                                Id = s.id,
                                DetailId = a.id,
                                OrderType = s.orderType,
                                OrderCode = s.code,
                                OrderDate = s.orderDate,
                                TraderCode = tt.code,
                                TraderName = tt.name,
                                TraderBill = s.traderBill,
                                MaterialId = m.id,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                IsNominal = m.isNominal,
                                PrjtId = m.projectId,
                                PrjtCode = m.projectCode,
                                IsProduce = s.isProduce,
                                Specs = a.specs,
                                Category = cc.name,
                                OperatorName = uu.name,
                                BusinessName = uu2.name,
                                Address = s.address,
                                AssesorName = uu1.name,
                                DetailMemo = a.memo,
                                IsClosed = s.isClosed,
                                Num = a.num,
                                FinishedNum = a.finishedNum,
                                DeliveryDate = s.deliveryDate,
                                PrevId = a.prevId,
                                PrevCode = a.prevCode,
                                PrevType = a.prevType,
                                Status = s.status,
                                IsVerify = s.isVerify
                            };
                return query;

            }
            catch { }
            return null;
        }


        /// <summary>
        /// 新增订单
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>        
        public int AddOrder(TB_Order obj)
        {
            try
            {
                dc.TB_Order.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新订单
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="details"></param>
        /// <returns></returns>
        public bool UpdateOrder(TB_Order obj, bool updateSubs)
        {
            try
            {
                var o = dc.TB_Order.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_OrderDetail).Name, typeof(TB_ShippingDetail).Name, typeof(TB_Trader).Name });

                    if (updateSubs)
                    {
                        //清除原明细数据
                        dc.TB_OrderDetail.DeleteAllOnSubmit(o.TB_OrderDetail);

                        foreach (TB_OrderDetail qcd in obj.TB_OrderDetail)
                        {
                            TB_OrderDetail nQcd = new TB_OrderDetail();
                            Common.objEval(qcd, nQcd, new List<string> { typeof(TB_Material).Name, typeof(TB_Order).Name, typeof(TB_ReqDetail).Name });
                            o.TB_OrderDetail.Add(nQcd);
                        }
                    }
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }


        /// <summary>
        /// 删除订单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteOrder(int id)
        {
            try
            {
                var data = dc.TB_Order.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }
        #endregion

        #region 订单明细
        /// <summary>
        /// 获取单个带关联的订单明细
        /// </summary>
        /// <param name="id">订单明细系统编码</param>
        /// <returns>XOrderDetail</returns>
        public XOrderDetail GetXOrderDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_OrderDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_OrderDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join c in dc.TB_Options on mm.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            //join p in dc.TB_ProductProject on r.material equals p.material into t_prdtPrjt
                            //from pp in t_prdtPrjt.DefaultIfEmpty()
                            select new XOrderDetail()
                            {
                                OrderDetail = r,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                MtrlMemo = mm.memo,
                                Expire = mm.expire,
                                Unit = mm.unit,
                                PrdtPrjtCode = mm.projectCode
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据订单获取带关联的订单明细
        /// </summary>
        /// <param name="id">订单系统编码</param>
        /// <returns>XOrderDetail序列</returns>
        public IEnumerable<XOrderDetail> GetXOrderDetails(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_OrderDetail>();
                predicate = predicate.And(p => p.orderId == id);

                var query = from r in (dc.TB_OrderDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join c in dc.TB_Options on mm.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            //join p in dc.TB_ProductProject on r.material equals p.material into t_prdtPrjt
                            //from pp in t_prdtPrjt.DefaultIfEmpty()
                            select new XOrderDetail()
                            {
                                OrderDetail = r,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                MtrlMemo = mm.memo,
                                Expire = mm.expire,
                                Unit = mm.unit,
                                PrdtPrjtCode = mm.projectCode
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增报价明细
        /// </summary>
        /// <param name="obj">TB_ReqDetail</param>
        /// <returns>新增报价明细系统编号</returns>
        public int AddOrderDetail(TB_OrderDetail obj)
        {
            try
            {
                dc.TB_OrderDetail.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }
        #endregion

        #region 库存管理
        /// <summary>
        /// 查找带关联的物料库存批次情况
        /// </summary>
        /// <param name="id"></param>
        public IEnumerable<XStock> GetBatchStocks(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Stock>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.material == id);
                var query = from s in (dc.TB_Stock.Where(predicate))
                            join m in dc.TB_Material on s.material equals m.id
                            join d in dc.TB_Depot on s.depot equals d.id
                            select new XStock()
                            {
                                Stock = s,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Unit = m.unit,
                                DepotCode = d.code,
                                DepotName = d.name
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 获取材料当前库存
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public decimal? GetCurrentStock(int id)
        {
            try
            {
                var q = dc.TB_Stock.Where(p => p.material == id).Sum(p => p.num);
                return q;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 库存单据查询存储过程
        /// </summary>
        /// <param name="sDate"></param>
        /// <param name="eDate"></param>
        /// <param name="category"></param>
        /// <param name="material"></param>
        /// <param name="depotCategory"></param>
        /// <param name="depot"></param>
        /// <returns></returns>
        public QStockBill[] QueryStockIO(DateTime? sDate, DateTime? eDate, int? category, int? material, int? depotCategory, int? depot)
        {

            try
            {
                using (SqlConnection con = new SqlConnection(dc.Connection.ConnectionString))
                {
                    SqlCommand cmd = new SqlCommand("QueryStockIO", con);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new SqlParameter("@DateBegin", sDate));
                    cmd.Parameters.Add(new SqlParameter("@DateEnd", eDate));
                    cmd.Parameters.Add(new SqlParameter("@MtrlCtgrId", category));
                    cmd.Parameters.Add(new SqlParameter("@MaterialId", material));
                    cmd.Parameters.Add(new SqlParameter("@DpotCtgrId", depotCategory));
                    cmd.Parameters.Add(new SqlParameter("@DepotId", depot));
                    con.Open();
                    SqlDataReader dr = cmd.ExecuteReader();
                    List<QStockBill> ary = new List<QStockBill>();
                    while (dr.Read())
                    {
                        QStockBill obj = new QStockBill();
                        PropertyInfo[] properties = obj.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        foreach (PropertyInfo item in properties)
                        {
                            object value = null;
                            if (dr[item.Name] != DBNull.Value)
                                value = dr[item.Name];
                            item.SetValue(obj, value, null);
                        }
                        ary.Add(obj);
                    }
                    con.Close();
                    return ary.ToArray();
                }
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 库存金额查询
        /// </summary>
        /// <param name="materialCategory">物资分类</param>
        /// <param name="depotCategory">仓库分类</param>
        /// <param name="depot">仓库id</param>
        /// <returns></returns>
        public QStockAmount[] QueryStockAmount(int? materialCategory, int? depotCategory, int? depot)
        {
            try
            {
                using (SqlConnection con = new SqlConnection(dc.Connection.ConnectionString))
                {
                    SqlCommand cmd = new SqlCommand("QueryStockAmount", con);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new SqlParameter("@MtrlCtgrId", materialCategory));
                    cmd.Parameters.Add(new SqlParameter("@DpotCtgrId", depotCategory));
                    cmd.Parameters.Add(new SqlParameter("@DepotId", depot));
                    con.Open();
                    SqlDataReader dr = cmd.ExecuteReader();
                    List<QStockAmount> ary = new List<QStockAmount>();
                    while (dr.Read())
                    {
                        QStockAmount obj = new QStockAmount();
                        PropertyInfo[] properties = obj.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        foreach (PropertyInfo item in properties)
                        {
                            object value = null;
                            if (dr[item.Name] != DBNull.Value)
                                value = dr[item.Name];
                            item.SetValue(obj, value, null);
                        }
                        ary.Add(obj);
                    }
                    con.Close();
                    return ary.ToArray();
                }
            }
            catch { }
            return null;
        }
        #endregion

        #region 单据审批
        /// <summary>
        /// 单据审批
        /// </summary>
        /// <param name="billType"></param>
        /// <param name="billId"></param>
        /// <param name="operatorId"></param>
        /// <param name="verify"></param>
        /// <returns></returns>        
        public VerifyBillResult VerifyBill(string billType, int billId, int operatorId, bool verify)
        {
            VerifyBillResult r = new VerifyBillResult();
            try
            {
                int? isOk = -1;
                string msg = string.Empty;
                dc.BillCheck(billType, billId, operatorId, verify, ref isOk, ref msg);
                r.Message = msg;
                r.Pass = isOk == 0;
            }
            catch { }
            return r;
        }
        #endregion

        #endregion

        #region 生产管理部分

        #region 领料单
        /// <summary>
        /// 获取单个领料单
        /// </summary>
        /// <param name="id">领料单id</param>
        /// <returns>TB_RecvMaterial</returns>
        public TB_RecvMaterial GetRecvMaterial(int id)
        { return dc.TB_RecvMaterial.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 带关联的领料单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XRecvMaterial GetXRecvMaterial(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_RecvMaterial>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_RecvMaterial.Where(predicate))
                            join u1 in dc.TB_User on r.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on r.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on r.businessman equals u3.id into t_businessman
                            from uu3 in t_businessman.DefaultIfEmpty()
                            join u4 in dc.TB_User on r.mender equals u4.id into t_mender
                            from uu4 in t_mender.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XRecvMaterial()
                            {
                                RecvMaterial = r,
                                OperatorCode = uu1.code,
                                OperatorName = uu1.name,
                                AssessorCode = uu2.code,
                                AssessorName = uu2.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                BusinessCode = uu3.code,
                                BusinessName = uu3.name,
                                MenderCode = uu4.code,
                                MenderName = uu4.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索领料单
        /// </summary>
        /// <param name="code">领料单代号</param>
        /// <param name="operatorName">制单人</param>
        /// <param name="status">状态</param>
        /// <param name="sDate">开始时间</param>
        /// <param name="eDate">结束时间</param>
        /// <param name="materailCode">物料代号</param>
        /// <param name="materialCategory">物料分类</param>
        /// <param name="materialName">物料名称</param>
        /// <returns></returns>
        public IEnumerable<QRecvMaterial> FindRecvMaterials(string code, string operatorName, string status, DateTime? sDate, DateTime? eDate, string materailCode, int? materialCategory, string materialName)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_RecvMaterial>();
                predicate = predicate.And(p => !p.deleteFlag);

                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.recvDate >= sDate);
                    predicate = predicate.And(p => p.recvDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (materialCategory != null)
                    predicate2 = predicate2.And(p => p.category == materialCategory);
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materailCode));
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Options>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (materialCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(materialCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(materialCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.id.ToString()));
                }

                var query = from s in (dc.TB_RecvMaterial.Where(predicate))
                            join a in dc.TB_RecvDetail on s.id equals a.recvMaterial
                            join m in (dc.TB_Material.Where(predicate2)) on a.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join c in (dc.TB_Options.Where(predicate3)) on mm.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            select new QRecvMaterial()
                            {
                                Id = s.id,
                                RqrtCode = s.code,
                                OrderCode = a.orderCode,
                                RecvMtrlCode = a.recvMtrlCode,
                                RecvDate = s.recvDate,
                                MaterialCode = mm.code,
                                Specs = a.specs,
                                Num = a.num,
                                DepartmentName = dd.name,
                                OperatorName = uu.name,
                                AssessorName = uu1.name,
                                MaterialCategory = cc.name,
                                Memo = s.memo,
                                DetialMemo = a.memo,
                                Type = s.type,
                                MaterialName = mm.cnName,
                                Status = s.status,
                                IsVerify = s.isVerify
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增领料单
        /// </summary>
        /// <param name="obj">领料单</param>
        /// <returns>新增领料单系统编号</returns>
        public int AddRecvMaterial(TB_RecvMaterial obj)
        {
            try
            {
                dc.TB_RecvMaterial.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新领料单
        /// </summary>
        /// <param name="requisition">领料单类型</param>
        /// <param name="requisitionDetails">领料明细</param>
        /// <returns>更新是否成功</returns>
        public bool UpdateRecvMaterial(TB_RecvMaterial obj, bool updateSubs)
        {

            //try
            //{
            //    var o = dc.TB_RecvMaterial.SingleOrDefault(d => d.id == obj.id);
            //    if (o != null)
            //    {
            //        Common.objEval(obj, o, new List<string> { typeof(TB_RecvDetail).Name });
            //        bool ok = false;
            //        if (details != null)
            //        {
            //            var qcds = from d in dc.TB_RecvDetail where d.recvMaterial == o.id select d;
            //            foreach (TB_RecvDetail qcd in qcds)//清除原明细数据
            //                o.TB_RecvDetail.Remove(qcd);

            //            foreach (TB_RecvDetail qcd in details)
            //                o.TB_RecvDetail.Add(qcd);
            //        }

            //        dc.SubmitChanges();
            //        return ok;
            //    }
            //}
            //catch { }
            //return false;
            try
            {
                var o = dc.TB_RecvMaterial.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_RecvDetail).Name });

                    if (updateSubs)
                    {
                        //清除原明细数据
                        dc.TB_RecvDetail.DeleteAllOnSubmit(o.TB_RecvDetail);

                        foreach (TB_RecvDetail qcd in obj.TB_RecvDetail)
                        {
                            TB_RecvDetail nQcd = new TB_RecvDetail();
                            Common.objEval(qcd, nQcd, new List<string> { typeof(TB_Material).Name, typeof(TB_RecvMaterial).Name });
                            o.TB_RecvDetail.Add(nQcd);
                        }
                    }
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除领料单
        /// </summary>
        /// <param name="id">领料单系统编号</param>
        /// <returns>删除是否成功</returns>        
        public bool DeleteRecvMaterial(int id)
        {
            try
            {
                var data = dc.TB_RecvMaterial.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        #endregion

        #region 领料明细
        /// <summary>
        /// 获取单个领料明细
        /// </summary>
        /// <param name="id">领料明细Id</param>
        /// <returns>TB_RecvDetail</returns>
        public TB_RecvDetail GetRecvDetail(int id)
        { return dc.TB_RecvDetail.SingleOrDefault(d => d.id == id); }

        /// <summary>
        /// 获取带关联的单个领料明细
        /// </summary>
        /// <param name="id">领料明细id</param>
        /// <returns>XRecvDetail</returns>
        public XRecvDetail GetXRecvDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_RecvDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_RecvDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join d in dc.TB_Depot on r.depot equals d.id into t_depot
                            from dd in t_depot.DefaultIfEmpty()
                            join o in dc.TB_Options on mm.category equals o.id into t_category
                            from oo in t_category.DefaultIfEmpty()
                            select new XRecvDetail()
                            {
                                RecvDetail = r,
                                MaterialName = mm.cnName,
                                Expire = mm.expire,
                                Unit = mm.unit,
                                DepotCode = dd.code,
                                DepotName = dd.name,
                                Brand = mm.brand,
                                CategoryCode = oo.code,
                                CategoryName = oo.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据领料单Id获取领料明细
        /// </summary>
        /// <param name="id">领料单Id</param>
        /// <returns>IEnumerable<XRecvDetail></returns>
        public IEnumerable<XRecvDetail> GetRecvDetails(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_RecvDetail>();
                predicate = predicate.And(p => p.recvMaterial == id);

                var query = from r in (dc.TB_RecvDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join d in dc.TB_Depot on r.depot equals d.id into t_depot
                            from dd in t_depot.DefaultIfEmpty()
                            join o in dc.TB_Options on mm.category equals o.id into t_category
                            from oo in t_category.DefaultIfEmpty()
                            select new XRecvDetail()
                            {
                                RecvDetail = r,
                                MaterialName = mm.cnName,
                                Expire = mm.expire,
                                Unit = mm.unit,
                                DepotCode = dd.code,
                                DepotName = dd.name,
                                Brand = mm.brand,
                                CategoryCode = oo.code,
                                CategoryName = oo.name
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增领料明细
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddRecvDetail(TB_RecvDetail obj)
        {
            try
            {
                dc.TB_RecvDetail.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }
        #endregion

        #endregion

        #region MRP部分

        #region 工程审批
        /// <summary>
        /// 工程审批
        /// </summary>
        /// <param name="prjtId"></param>
        /// <param name="prjtCode"></param>
        /// <param name="pass"></param>
        /// <param name="verifyStatus"></param>
        /// <returns></returns>        
        public bool VerifyPrdtPrjt(int prjtId, string prjtCode, bool pass, short verifyStatus)
        {
            try
            {
                bool? ok = false;
                dc.VerifyProductProject(prjtId, prjtCode, pass, verifyStatus, ref ok);
                return Convert.ToBoolean(ok);
            }
            catch { }
            return false;
        }

        #endregion

        #region 产品工程
        /// <summary>
        /// 获取一个产品工程资料
        /// </summary>
        /// <param name="id">产品工程系统编码</param>
        /// <returns></returns>
        public TB_ProductProject GetPrdtPrjt(int id)
        {
            return dc.TB_ProductProject.SingleOrDefault(d => d.id == id && !d.deleteFlag);
        }

        /// <summary>
        /// 获取带关联的产品工程
        /// </summary>
        /// <param name="id">工程Id</param>
        /// <returns>XPrdtPrjt</returns>
        public XPrdtPrjt GetXPrdtPrjt(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProductProject>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var query = from p in (dc.TB_ProductProject.Where(predicate))
                            join u in dc.TB_User on p.engineer equals u.id into t_engineer
                            from uu in t_engineer.DefaultIfEmpty()
                            join m in dc.TB_Material on p.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join u1 in dc.TB_User on p.submitMan equals u1.id into t_submitMan
                            from uu1 in t_submitMan.DefaultIfEmpty()
                            join u2 in dc.TB_User on p.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join d in dc.TB_Department on p.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XPrdtPrjt()
                            {
                                PrdtPrjt = p,
                                MaterialCode = mm.code,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                EngineerCode = uu.code,
                                EngineerName = uu.name,
                                SubmitManCode = uu1.code,
                                SubmitManName = uu.name,
                                AssessorCode = uu2.code,
                                AssessorName = uu2.name,
                                CategoryId = mm.category
                            };
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据元件Id获取相关工程
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<XPrdtPrjt> GetXPrdtPrjts(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProductProject>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.material == id);

                var query = from p in (dc.TB_ProductProject.Where(predicate))
                            join u in dc.TB_User on p.engineer equals u.id into t_engineer
                            from uu in t_engineer.DefaultIfEmpty()
                            join m in dc.TB_Material on p.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join u1 in dc.TB_User on p.submitMan equals u1.id into t_submitMan
                            from uu1 in t_submitMan.DefaultIfEmpty()
                            join u2 in dc.TB_User on p.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join d in dc.TB_Department on p.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XPrdtPrjt()
                            {
                                PrdtPrjt = p,
                                MaterialCode = mm.code,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                EngineerCode = uu.code,
                                EngineerName = uu.name,
                                SubmitManCode = uu1.code,
                                SubmitManName = uu.name,
                                AssessorCode = uu2.code,
                                AssessorName = uu2.name,
                                CategoryId = mm.category
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据工程元件ID获取下级工程
        /// </summary>
        /// <param name="id">工程元件ID</param>
        /// <returns>TB_ProductProject</returns>
        public TB_ProductProject GetSubPrdtPrjt(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProductProject>();
                predicate = predicate.And(p => !p.deleteFlag);

                var predicate1 = PredicateBuilder.True<TB_ProjectElement>();
                predicate1 = predicate1.And(p => !p.deleteFlag);
                predicate1 = predicate1.And(p => p.id == id);

                var query = from s in (dc.TB_ProductProject.Where(predicate))
                            join e in (dc.TB_ProjectElement.Where(predicate1)) on s.id equals e.nextPrjt
                            select s;
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 返回所有带关联的产品工程
        /// </summary>
        /// <returns></returns>
        public IEnumerable<XPrdtPrjt> GetPrdtPrjts()
        {
            //try
            //{
            //    var predicate = PredicateBuilder.True<TB_ProductProject>();
            //    predicate = predicate.And(p => !p.deleteFlag);

            //    var query = from s in (dc.TB_ProductProject.Where(predicate))
            //                join m in dc.TB_Material on s.material equals m.id into t_material
            //                from mm in t_material.DefaultIfEmpty()
            //                select new PrdtPrjtNode()
            //                       {
            //                           Id = s.id,
            //                           Code = s.code,
            //                           Version = s.version,
            //                           IsStandard = s.isStandard,
            //                           MaterialId = mm.id,
            //                           MaterialCode = mm.code,
            //                           MaterialName = mm.cnName,
            //                           Specs = mm.specs,
            //                           CategoryId = mm.category,
            //                           IsSubmit = s.isSubmit,
            //                           SubmitStatus = s.submitStatus,
            //                           IsVerify = s.isVerify,
            //                           VerifyStatus = s.verifyStatus,
            //                           IsRelease = s.isRelease
            //                       };
            //    return query;
            //}
            //catch { }
            //return null;
            try
            {
                var predicate = PredicateBuilder.True<TB_ProductProject>();
                predicate = predicate.And(p => !p.deleteFlag);

                var query = from p in (dc.TB_ProductProject.Where(predicate))
                            join u in dc.TB_User on p.engineer equals u.id into t_engineer
                            from uu in t_engineer.DefaultIfEmpty()
                            join m in dc.TB_Material on p.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            join u1 in dc.TB_User on p.submitMan equals u1.id into t_submitMan
                            from uu1 in t_submitMan.DefaultIfEmpty()
                            join u2 in dc.TB_User on p.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join d in dc.TB_Department on p.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XPrdtPrjt()
                            {
                                PrdtPrjt = p,
                                MaterialCode = mm.code,
                                MaterialName = mm.cnName,
                                Specs = mm.specs,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                EngineerCode = uu.code,
                                EngineerName = uu.name,
                                SubmitManCode = uu1.code,
                                SubmitManName = uu.name,
                                AssessorCode = uu2.code,
                                AssessorName = uu2.name,
                                CategoryId = mm.category
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索产品工程，
        /// </summary>
        /// <param name="isVerify">工程是否已审批，引用工程的时候工程必须已审批</param>
        /// <param name="category">物料类别</param>
        /// <param name="depotCategory">仓库类别</param>
        /// <param name="depot">仓库</param>
        /// <param name="code">产品工程代号</param>
        /// <param name="version">版本号</param>
        /// <param name="engineerName">工程师名称</param>
        /// <param name="submitStatus">提交状态</param>
        /// <param name="verifyStatus">审批状态</param>
        /// <param name="materialCode">物料代号</param>
        /// <param name="materialName">物料名称</param>
        /// <returns>XPrdtPrjt序列</returns>
        public IEnumerable<QPrdtPrjt> FindPrdtPrjt(bool? isVerify, int? category, int? depotCategory, int? depot, string code, string version, string engineerName,
            short? submitStatus, short? verifyStatus, string materialCode, string materialName)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProductProject>();
                predicate = predicate.And(p => !p.deleteFlag);

                if (isVerify != null)
                    predicate = predicate.And(p => p.isVerify == isVerify);
                if (submitStatus != null)
                    predicate = predicate.And(p => p.submitStatus == submitStatus);
                if (verifyStatus != null)
                    predicate = predicate.And(p => p.verifyStatus == verifyStatus);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));
                if (!string.IsNullOrEmpty(version))
                    predicate = predicate.And(p => p.version.Contains(version));

                var predicate1 = PredicateBuilder.True<TB_User>();
                predicate1 = predicate1.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(engineerName))
                    predicate1 = predicate1.And(p => p.name.Contains(engineerName));

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (category != null)
                    predicate2 = predicate2.And(p => p.category == category);
                if (!string.IsNullOrEmpty(materialCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materialCode));
                if (!string.IsNullOrEmpty(materialName))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Depot>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (depot != null)
                {
                    predicate3 = predicate3.And(p => p.id == depot);
                }

                if (depotCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(depotCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.仓库分类.ToString(), Convert.ToInt32(depotCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.type.ToString()));
                }

                var query = from s in (dc.TB_ProductProject.Where(predicate))
                            join u in (dc.TB_User.Where(predicate1)) on s.engineer equals u.id into t_engineer
                            from uu in t_engineer.DefaultIfEmpty()
                            join m in (dc.TB_Material.Where(predicate2)) on s.material equals m.id
                            join u1 in dc.TB_User on s.submitMan equals u1.id into t_submitMan
                            from uu1 in t_submitMan.DefaultIfEmpty()
                            join u2 in dc.TB_User on s.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join s1 in dc.TB_Stock on s.material equals s1.material into t_stock
                            from ss1 in t_stock.DefaultIfEmpty()
                            join d1 in (dc.TB_Depot.Where(predicate3)) on ss1.depot equals d1.id into t_stockDepot
                            from dd1 in t_stockDepot.DefaultIfEmpty()
                            select new QPrdtPrjt()
                            {
                                Id = s.id,
                                Code = s.code,
                                //MaterialId = mm.id,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Specs = m.specs,
                                Version = s.version,
                                IsStandard = s.isStandard,
                                EngineerName = uu.name,
                                IsSubmit = s.isSubmit,
                                SubmitManName = uu1.name,
                                SubmitStatus = s.submitStatus,
                                VerifyStatus = s.verifyStatus,
                                AssessorName = uu2.name,
                                CreateTime = s.createTime,
                                UpdateTime = s.updateTime,
                                DepartmentName = dd.name,
                                PicCode = string.Empty,
                                IsVerify = s.isVerify,
                                Hours = s.hours
                            };
                return query.Distinct();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增产品工程
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddPrdtPrjt(TB_ProductProject obj)
        {
            try
            {
                dc.TB_ProductProject.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新产品工程
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool UpdatePrdtPrjt(TB_ProductProject obj)
        {
            try
            {
                var o = dc.TB_ProductProject.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_Material).Name, typeof(TB_ProjectWorkstage).Name });
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除产品工程
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeletePrdtPrjt(int id)
        {
            try
            {
                var q1 = from w in dc.TB_ProjectWorkstage where w.project == id select w;
                foreach (TB_ProjectWorkstage ww in q1)
                {
                    var q = from e in dc.TB_ProjectElement where e.projectWorkstage == ww.id select e;
                    foreach (TB_ProjectElement ee in q)
                        ee.deleteFlag = true;
                    ww.deleteFlag = true;
                }

                var data = dc.TB_ProductProject.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }
        /// <summary>
        /// 根据产品工程id获取工序序号
        /// </summary>
        /// <param name="type">1=工序序号，2-元件序号</param>
        /// <param name="id">产品工程Id或工程工序id</param>
        /// <returns></returns>
        public string GetPrdtPrjtSerialNo(int type, int id)
        {
            try
            {
                int? no = 0;
                dc.GetPrdtPrjtNo(type, id, ref no);
                return no.ToString();
            }
            catch { }
            return string.Empty;
        }

        /// <summary>
        /// 复制产品工程
        /// </summary>
        /// <param name="sPrjt">复制源工程</param>
        /// <param name="dPrjt">目标工程</param>
        /// <returns></returns>
        public bool CopyPrdtPrjt(int sPrjt, int dPrjt)
        {
            //1、清除目标工程原结构 2、复制源结构，3、加载前端树结构
            try
            {
                TB_ProductProject pp = dc.TB_ProductProject.SingleOrDefault(d => d.id == dPrjt && !d.deleteFlag);
                if (pp != null)
                {
                    var pws = from w in dc.TB_ProjectWorkstage where w.project == pp.id select w;
                    if (pws != null)
                    {
                        foreach (TB_ProjectWorkstage pw in pws)
                        {
                            pw.deleteFlag = true;
                            pw.TB_ProjectElement.Clear();
                        }
                        pp.TB_ProjectWorkstage.Clear();
                    }


                    var pws1 = from w in dc.TB_ProjectWorkstage where w.project == sPrjt select w;
                    if (pws1 != null)
                    {
                        foreach (TB_ProjectWorkstage pw in pws1)
                        {
                            TB_ProjectWorkstage w = new TB_ProjectWorkstage();
                            Common.objEval(pw, w, new List<string> { typeof(TB_ProductProject).Name, typeof(TB_ProjectElement).Name, typeof(TB_Workstage).Name });
                            w.prjtCode = pp.code;
                            var pes = from e in dc.TB_ProjectElement where e.projectWorkstage == pw.id select e;
                            if (pes != null)
                            {
                                foreach (TB_ProjectElement pe in pes)
                                {
                                    TB_ProjectElement e = new TB_ProjectElement();
                                    Common.objEval(pe, e, new List<string> { typeof(TB_Material).Name, typeof(TB_ProjectWorkstage).Name });
                                    w.TB_ProjectElement.Add(e);
                                }
                            }
                            pp.TB_ProjectWorkstage.Add(w);
                        }
                    }

                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 产品工序
        /// <summary>
        /// 根据产品工序Id获取单个产品工序信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TB_ProjectWorkstage GetPrjtWorkstage(int id)
        {
            return dc.TB_ProjectWorkstage.SingleOrDefault(d => d.id == id && !d.deleteFlag);
        }

        /// <summary>
        /// 根据产品工序Id获取单个带关联的产品工序
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>        
        public XPrjtWorkstage GetXPrjtWorkstage(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProjectWorkstage>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var predicate2 = PredicateBuilder.True<TB_Workstage>();
                predicate2 = predicate2.And(p => !p.deleteFlag);

                var query = from p in (dc.TB_ProjectWorkstage.Where(predicate))
                            join w in (dc.TB_Workstage.Where(predicate2)) on p.workstage equals w.id into t_workstage
                            from ww in t_workstage.DefaultIfEmpty()
                            select new XPrjtWorkstage()
                            {
                                PrjtWorkstage = p,
                                WorkstageCode = ww.code,
                                WorkstageName = ww.name
                            };
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        ///// <summary>
        ///// 根据物料id获取对应的工程工序树节点
        ///// </summary>
        ///// <param name="id">物料Id</param>
        ///// <returns>PrjtWorkstageNode</returns>        
        //public PrjtWorkstageNode GetPrjtWorkstageNode(int id)
        //{
        //    try
        //    {
        //        var predicate = PredicateBuilder.True<TB_ProjectWorkstage>();
        //        predicate = predicate.And(p => !p.deleteFlag);

        //        var predicate1 = PredicateBuilder.True<TB_ProjectElement>();
        //        predicate1 = predicate1.And(p => !p.deleteFlag);
        //        predicate1 = predicate1.And(p => p.material == id);

        //        var predicate2 = PredicateBuilder.True<TB_Workstage>();
        //        predicate2 = predicate2.And(p => !p.deleteFlag);

        //        var query = from p in (dc.TB_ProjectWorkstage.Where(predicate))
        //                    join w in (dc.TB_Workstage.Where(predicate2)) on p.workstage equals w.id into t_workstage
        //                    from ww in t_workstage.DefaultIfEmpty()
        //                    join e in (dc.TB_ProjectElement.Where(predicate1)) on p.id equals e.projectWorkstage into t_element
        //                    from ee in t_element.DefaultIfEmpty()
        //                    select new PrjtWorkstageNode()
        //                    {
        //                        Id = p.id,
        //                        PrjtId = p.project,
        //                        PrjtCode = p.prjtCode,
        //                        Sort = p.sort,
        //                        WorkstageId = p.workstage,
        //                        WorkstageCode = ww.code,
        //                        WorkstageName = ww.name
        //                    };
        //        return query.SingleOrDefault();
        //    }
        //    catch { }
        //    return null;

        //}

        ///// <summary>
        ///// 根据产品工程Id获取产品工程工序树节点类类型数据
        ///// </summary>
        ///// <param name="id">产品工程编号</param>
        ///// <returns>PrdtWorkstageNode</returns>        
        //public IEnumerable<PrjtWorkstageNode> FindPrjtWorkstages(int id)
        //{
        //    try
        //    {
        //        var predicate = PredicateBuilder.True<TB_ProjectWorkstage>();
        //        predicate = predicate.And(p => !p.deleteFlag);
        //        predicate = predicate.And(p => p.project == id);

        //        var query = from p in (dc.TB_ProjectWorkstage.Where(predicate))
        //                    join w in dc.TB_Workstage on p.workstage equals w.id into t_workstage
        //                    from ww in t_workstage.DefaultIfEmpty()
        //                    select new PrjtWorkstageNode()
        //                    {
        //                        Id = p.id,
        //                        PrjtId = p.project,
        //                        PrjtCode = p.prjtCode,
        //                        Sort = p.sort,
        //                        WorkstageId = p.workstage,
        //                        WorkstageCode = ww.code,
        //                        WorkstageName = ww.name
        //                    };
        //        return query;
        //    }
        //    catch { }
        //    return null;
        //}

        /// <summary>
        /// 搜索产品工序
        /// </summary>
        /// <param name="id">产品工程Id</param>
        /// <returns></returns>
        public IEnumerable<XPrjtWorkstage> FindPrjtWorkstages(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProjectWorkstage>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.project == id);

                var query = from p in (dc.TB_ProjectWorkstage.Where(predicate))
                            join w in dc.TB_Workstage on p.workstage equals w.id into t_workstage
                            from ww in t_workstage.DefaultIfEmpty()
                            select new XPrjtWorkstage()
                            {
                                PrjtWorkstage = p,
                                WorkstageCode = ww.code,
                                WorkstageName = ww.name
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增产品工序
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddPrjtWorkstage(TB_ProjectWorkstage obj)
        {
            try
            {
                dc.TB_ProjectWorkstage.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新产品工序
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool UpdatePrjtWorkstage(TB_ProjectWorkstage obj)
        {
            try
            {
                var o = dc.TB_ProjectWorkstage.SingleOrDefault(d => d.id == obj.id);
                //obj.TB_ProductProject = dc.TB_ProductProject.SingleOrDefault(p => p.id == obj.project);//产品工程外键
                //obj.TB_Workstage = dc.TB_Workstage.SingleOrDefault(w => w.id == obj.workstage);//工序外键
                if (o != null)
                {
                    List<string> list = new List<string> { typeof(TB_ProductProject).Name, typeof(TB_ProjectElement).Name, typeof(TB_Workstage).Name };
                    Common.objEval(obj, o, list);
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除产品工序
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeletePrjtWorkstage(int id)
        {
            try
            {
                var q = from e in dc.TB_ProjectElement where e.projectWorkstage == id select e;
                foreach (TB_ProjectElement ee in q)
                    ee.deleteFlag = true;

                var data = dc.TB_ProjectWorkstage.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 元件
        /// <summary>
        /// 获取单个工程元件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TB_ProjectElement GetPrjtElement(int id)
        {
            return dc.TB_ProjectElement.SingleOrDefault(d => d.id == id && !d.deleteFlag);
        }

        /// <summary>
        /// 获取元件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XPrjtElement GetXPrjtElement(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProjectElement>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);

                var predicate1 = PredicateBuilder.True<TB_ProjectWorkstage>();
                predicate1 = predicate1.And(p => !p.deleteFlag);

                var predicate2 = PredicateBuilder.True<TB_ProductProject>();
                predicate2 = predicate2.And(p => !p.deleteFlag);

                var predicate3 = PredicateBuilder.True<TB_ProductProject>();
                predicate3 = predicate3.And(p => !p.deleteFlag);

                var query = from p in (dc.TB_ProjectElement.Where(predicate))
                            join p1 in (dc.TB_ProjectWorkstage.Where(predicate1)) on p.projectWorkstage equals p1.id
                            join p2 in (dc.TB_ProductProject.Where(predicate2)) on p1.project equals p2.id
                            join p3 in (dc.TB_ProductProject.Where(predicate3)) on p.nextPrjt equals p3.id into t_nextPrjt
                            from pp3 in t_nextPrjt.DefaultIfEmpty()
                            join m in dc.TB_Material on p.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            select new XPrjtElement()
                            {
                                PrjtElement = p,
                                PrjtId = p2.id,
                                PrjtCode = p2.code,
                                MachiningSort = p1.sort,
                                MaterialName = mm.cnName,
                                Expire = mm.expire,
                                Specs = mm.specs,
                                Unit = mm.unit,
                                NextPrjtId = pp3.id,
                                NextPrjtCode = pp3.code,
                                NextPrjtIsSubmit = pp3.isSubmit,
                                NextPrjtIsVerify = pp3.isVerify
                            };
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        ///// <summary>
        ///// 根据工序id获取所需元件树节点
        ///// </summary>
        ///// <param name="id">工序id</param>
        ///// <returns></returns>
        //public IEnumerable<PrjtElementNode> FindPrjtElementNodes(int id)
        //{
        //    try
        //    {
        //        var predicate = PredicateBuilder.True<TB_ProjectElement>();
        //        predicate = predicate.And(p => !p.deleteFlag);
        //        predicate = predicate.And(p => p.projectWorkstage == id);

        //        var predicate1 = PredicateBuilder.True<TB_ProjectWorkstage>();
        //        predicate1 = predicate1.And(p => !p.deleteFlag);

        //        var predicate2 = PredicateBuilder.True<TB_ProductProject>();
        //        predicate2 = predicate2.And(p => !p.deleteFlag);

        //        var predicate3 = PredicateBuilder.True<TB_ProductProject>();
        //        predicate3 = predicate3.And(p => !p.deleteFlag);

        //        var query = from p in (dc.TB_ProjectElement.Where(predicate))
        //                    join p1 in (dc.TB_ProjectWorkstage.Where(predicate1)) on p.projectWorkstage equals p1.id
        //                    join p2 in (dc.TB_ProductProject.Where(predicate2)) on p1.project equals p2.id
        //                    join p3 in (dc.TB_ProductProject.Where(predicate3)) on p.nextPrjt equals p3.id into t_nextPrjt
        //                    from pp3 in t_nextPrjt.DefaultIfEmpty()
        //                    join m in dc.TB_Material on p.material equals m.id into t_material
        //                    from mm in t_material.DefaultIfEmpty()
        //                    select new PrjtElementNode()
        //                    {
        //                        Id = p.id,
        //                        Sort = p.sort,
        //                        PrjtWorkstageId = p.projectWorkstage,
        //                        MaterialId = p.material,
        //                        MaterialCode = mm.code,
        //                        MaterialName = mm.cnName,
        //                        Specs = mm.specs,
        //                        Dosage = p.dosage,
        //                        NextPrjtId = p.nextPrjt,
        //                        NextPrjtCode = p.nextPrjtCode,
        //                        PrjtWorkstageSort = p1.sort,
        //                        PrdtPrjtId = p2.id,
        //                        PrdtPrjtCode = p2.code,
        //                        NextPrjtIsSubmit = pp3.isSubmit,
        //                        NextPrjtIsVerify = pp3.isVerify
        //                    };
        //        return query;
        //    }
        //    catch { }
        //    return null;
        //}


        /// <summary>
        /// 根据工序id获取所需元件
        /// </summary>
        /// <param name="id">工序id</param>
        /// <returns></returns>
        public IEnumerable<XPrjtElement> FindPrjtElements(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_ProjectElement>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.projectWorkstage == id);

                var predicate1 = PredicateBuilder.True<TB_ProjectWorkstage>();
                predicate1 = predicate1.And(p => !p.deleteFlag);

                var predicate2 = PredicateBuilder.True<TB_ProductProject>();
                predicate2 = predicate2.And(p => !p.deleteFlag);

                var predicate3 = PredicateBuilder.True<TB_ProductProject>();
                predicate3 = predicate3.And(p => !p.deleteFlag);

                var query = from p in (dc.TB_ProjectElement.Where(predicate))
                            join p1 in (dc.TB_ProjectWorkstage.Where(predicate1)) on p.projectWorkstage equals p1.id
                            join p2 in (dc.TB_ProductProject.Where(predicate2)) on p1.project equals p2.id
                            join p3 in (dc.TB_ProductProject.Where(predicate3)) on p.nextPrjt equals p3.id into t_nextPrjt
                            from pp3 in t_nextPrjt.DefaultIfEmpty()
                            join m in dc.TB_Material on p.material equals m.id into t_material
                            from mm in t_material.DefaultIfEmpty()
                            select new XPrjtElement()
                            {
                                PrjtElement = p,
                                PrjtId = p2.id,
                                PrjtCode = p2.code,
                                MachiningSort = p1.sort,
                                MaterialName = mm.cnName,
                                Expire = mm.expire,
                                Specs = mm.specs,
                                Unit = mm.unit,
                                NextPrjtId = pp3.id,
                                NextPrjtCode = pp3.code,
                                NextPrjtIsSubmit = pp3.isSubmit,
                                NextPrjtIsVerify = pp3.isVerify
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增元件
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddPrjtElement(TB_ProjectElement obj)
        {
            try
            {
                dc.TB_ProjectElement.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新元件
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool UpdatePrjtElement(TB_ProjectElement obj)
        {
            try
            {
                var o = dc.TB_ProjectElement.SingleOrDefault(d => d.id == obj.id);
                //o.TB_Material = dc.TB_Material.SingleOrDefault(m => m.id == obj.material);//物料外键
                //o.TB_ProjectWorkstage = dc.TB_ProjectWorkstage.SingleOrDefault(p => p.id == obj.projectWorkstage);//工程工序外键
                if (o != null)
                {
                    List<string> list = new List<string> { typeof(TB_Material).Name, typeof(TB_ProjectWorkstage).Name };
                    Common.objEval(obj, o, list);
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除元件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeletePrjtElement(int id)
        {
            try
            {
                var data = dc.TB_ProjectElement.SingleOrDefault(d => d.id == id);
                if (data != null)
                {
                    data.deleteFlag = true;
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }
        #endregion

        #region 需求计划
        /// <summary>
        /// 获取单个需求计划单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TB_Requirement GetRequirement(int id)
        { return dc.TB_Requirement.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取带关联的需求计划单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XRequirement GetXRequirement(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Requirement>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);
                var query = from r in (dc.TB_Requirement.Where(predicate))
                            join u1 in dc.TB_User on r.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on r.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on r.mender equals u3.id into t_mender
                            from uu3 in t_mender.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XRequirement
                            {
                                Requirement = r,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                OperatorName = uu1.name,
                                AssessorName = uu2.name,
                                MenderName = uu3.name
                            };
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索复合类型的需求计划
        /// </summary>
        /// <param name="isRelease"></param>
        /// <returns></returns>
        public IEnumerable<XRequirement> GetXRequirements(bool? isRelease, string status)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Requirement>();
                predicate = predicate.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (isRelease != null)
                    predicate = predicate.And(p => p.isRelease == isRelease);

                var query = from r in (dc.TB_Requirement.Where(predicate))
                            join u1 in dc.TB_User on r.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on r.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on r.mender equals u3.id into t_mender
                            from uu3 in t_mender.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XRequirement
                            {
                                Requirement = r,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                OperatorName = uu1.name,
                                AssessorName = uu2.name,
                                MenderName = uu3.name
                            };
                return query;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索需求计划单
        /// </summary>
        /// <param name="code"></param>
        /// <param name="operatorName"></param>
        /// <param name="status"></param>
        /// <param name="orderCode"></param>
        /// <param name="sDate"></param>
        /// <param name="eDate"></param>
        /// <param name="isRelease"></param>
        /// <returns></returns>
        public IEnumerable<QRequirement> FindRequirements(string code, string operatorName, string status, string orderCode, DateTime? sDate, DateTime? eDate, bool? isRelease)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Requirement>();
                predicate = predicate.And(p => !p.deleteFlag);

                if (isRelease != null)
                    predicate = predicate.And(p => p.isRelease == isRelease);

                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.rqrtDate >= sDate);
                    predicate = predicate.And(p => p.rqrtDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate2 = PredicateBuilder.True<TB_User>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(operatorName))
                    predicate2 = predicate2.And(p => p.name.Contains(operatorName));

                var predicate3 = PredicateBuilder.True<TB_Order>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (!string.IsNullOrEmpty(orderCode))
                    predicate3 = predicate3.And(p => p.code.Contains(orderCode));

                var query = from s in (dc.TB_Requirement.Where(predicate))
                            join u in (dc.TB_User.Where(predicate2)) on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            join a in dc.TB_RqrtDetail on s.id equals a.rqrt
                            join m in dc.TB_Material on a.material equals m.id
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new QRequirement()
                            {
                                Id = s.id,
                                Code = s.code,
                                OrderCode = s.orderCode,
                                RqrtDate = s.rqrtDate,
                                OperatorName = uu.name,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Specs = a.specs,
                                DepartmentName = dd.name,
                                IsRelease = a.isRelease,
                                Status = s.status,
                                AssessorName = uu1.name
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增需求计划
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddRequirement(TB_Requirement obj)
        {
            try
            {
                dc.TB_Requirement.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新需求计划
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="updateSubs">子表是否同步更新</param>
        /// <returns></returns>
        public bool UpdateRequirement(TB_Requirement obj, bool updateSubs)
        {
            try
            {
                var o = dc.TB_Requirement.SingleOrDefault(d => d.id == obj.id);
                if (o != null)
                {
                    Common.objEval(obj, o, new List<string> { typeof(TB_RqrtDetail).Name });
                    if (updateSubs)
                    {
                        //o.TB_RqrtDetail.Clear();//清除原明细数据
                        dc.TB_RqrtDetail.DeleteAllOnSubmit(o.TB_RqrtDetail);

                        foreach (TB_RqrtDetail qcd in obj.TB_RqrtDetail)
                        {
                            TB_RqrtDetail nQcd = new TB_RqrtDetail();
                            Common.objEval(qcd, nQcd, new List<string> { typeof(TB_Material).Name, typeof(TB_Requirement).Name });
                            o.TB_RqrtDetail.Add(nQcd);
                        }
                    }
                    dc.SubmitChanges();
                    return true;
                }
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除需求计划
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteRequirement(int id)
        {
            try
            {
                var data = dc.TB_Requirement.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }
        #endregion

        #region 需求计划明细
        /// <summary>
        /// 更新需求明细
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>        
        public bool UpdateRqrtDetail(TB_RqrtDetail[] objs)
        {
            try
            {
                List<string> list = new List<string> { typeof(TB_Material).Name, typeof(TB_Requirement).Name };

                foreach (TB_RqrtDetail obj in objs)
                {
                    var o = dc.TB_RqrtDetail.SingleOrDefault(d => d.id == obj.id);
                    if (o != null)
                        Common.objEval(obj, o, list);

                }
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }


        /// <summary>
        /// 获取带关联的需求计划明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XRqrtDetail GetXRqrtDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_RqrtDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_RqrtDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id
                            join o in dc.TB_Options on m.category equals o.id into t_category
                            from oo in t_category.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XRqrtDetail()
                            {
                                RqrtDetail = r,
                                MaterialName = m.cnName,
                                CategoryName = oo.name,
                                Unit = m.unit,
                                DepartmentName = dd.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据需求计划单ID货相关明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<XRqrtDetail> GetXRqrtDetails(int[] ids)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_RqrtDetail>();
                predicate = predicate.And(p => ids.Contains(p.rqrt));

                var query = from r in (dc.TB_RqrtDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id
                            join o in dc.TB_Options on m.category equals o.id into t_category
                            from oo in t_category.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XRqrtDetail()
                            {
                                RqrtDetail = r,
                                MaterialName = m.cnName,
                                CategoryName = oo.name,
                                Unit = m.unit,
                                DepartmentName = dd.name
                            };
                return query;

            }
            catch { }
            return null;
        }
        #endregion

        #region 生产单
        /// <summary>
        /// 获取单个生产单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TB_Production GetProduction(int id)
        { return dc.TB_Production.SingleOrDefault(d => d.id == id && !d.deleteFlag); }

        /// <summary>
        /// 获取带关联的生产单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XProduction GetXProduction(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Production>();
                predicate = predicate.And(p => !p.deleteFlag);
                predicate = predicate.And(p => p.id == id);
                var query = from p in (dc.TB_Production.Where(predicate))
                            join u1 in dc.TB_User on p.@operator equals u1.id into t_operator
                            from uu1 in t_operator.DefaultIfEmpty()
                            join u2 in dc.TB_User on p.assessor equals u2.id into t_assessor
                            from uu2 in t_assessor.DefaultIfEmpty()
                            join u3 in dc.TB_User on p.mender equals u3.id into t_mender
                            from uu3 in t_mender.DefaultIfEmpty()
                            join d in dc.TB_Department on p.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XProduction
                            {
                                Production = p,
                                OperatorName = uu1.name,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                MenderName = uu3.name,
                                AssessorName = uu2.name
                            };
                return query.SingleOrDefault();
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 搜索生产单
        /// </summary>
        /// <param name="code"></param>
        /// <param name="operatorName"></param>
        /// <param name="status"></param>
        /// <param name="sDate"></param>
        /// <param name="eDate"></param>
        /// <param name="materailCode"></param>
        /// <param name="materialCategory"></param>
        /// <param name="materialName"></param>
        /// <param name="isCheck">是否经过质检</param>
        /// <returns></returns>
        public IEnumerable<QProduction> FindProductions(string code, string operatorName, string status, DateTime? sDate, DateTime? eDate, string materailCode, int? materialCategory, string materialName, bool? isCheck)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_Production>();
                predicate = predicate.And(p => !p.deleteFlag);

                if (sDate != null && eDate != null)
                {
                    predicate = predicate.And(p => p.pDate >= sDate);
                    predicate = predicate.And(p => p.pDate <= eDate);
                }
                if (!string.IsNullOrEmpty(status))
                    predicate = predicate.And(p => p.status == status);
                if (!string.IsNullOrEmpty(code))
                    predicate = predicate.And(p => p.code.Contains(code));

                var predicate2 = PredicateBuilder.True<TB_Material>();
                predicate2 = predicate2.And(p => !p.deleteFlag);
                if (materialCategory != null)
                    predicate2 = predicate2.And(p => p.category == materialCategory);
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.code.Contains(materailCode));
                if (!string.IsNullOrEmpty(materailCode))
                    predicate2 = predicate2.And(p => p.cnName.Contains(materialName));

                var predicate3 = PredicateBuilder.True<TB_Options>();
                predicate3 = predicate3.And(p => !p.deleteFlag);
                if (materialCategory != null)
                {
                    ArrayList aryList = new ArrayList();
                    aryList.Add(materialCategory.ToString());
                    Common.TrasOptions(ref aryList, dc, GRWL.BZSC.Common.EnumCommon.OptionType.物料分类.ToString(), Convert.ToInt32(materialCategory));
                    string[] ary = (string[])aryList.ToArray(typeof(string));
                    predicate3 = predicate3.And(p => ary.Contains(p.id.ToString()));
                }

                var predicate4 = PredicateBuilder.True<TB_Order>();
                if (isCheck != null)
                    predicate4 = predicate4.And(p => p.isCheck == isCheck);

                var query = from s in (dc.TB_Production.Where(predicate))
                            join a in dc.TB_PrdnDetail on s.id equals a.prdn
                            join o1 in (dc.TB_Order.Where(predicate4)) on a.orderId equals o1.id into t_order
                            from oo1 in t_order.DefaultIfEmpty()
                            join m in (dc.TB_Material.Where(predicate2)) on a.material equals m.id
                            join c in (dc.TB_Options.Where(predicate3)) on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join u in dc.TB_User on s.@operator equals u.id into t_operator
                            from uu in t_operator.DefaultIfEmpty()
                            join u1 in dc.TB_User on s.assessor equals u1.id into t_assessor
                            from uu1 in t_assessor.DefaultIfEmpty()
                            join d in dc.TB_Department on s.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            join d1 in dc.TB_Department on a.department equals d1.id into t_detaildepartment
                            from dd1 in t_detaildepartment.DefaultIfEmpty()
                            //join t in dc.TB_Trader on s.trader equals t.id into t_trader
                            //from tt in t_trader.DefaultIfEmpty()
                            join r in dc.TB_Requirement on a.rqrtId equals r.id into t_requirement
                            from rr in t_requirement.DefaultIfEmpty()
                            select new QProduction()
                            {
                                Id = s.id,
                                Code = s.code,
                                OrderCode = oo1.code,
                                OrderDate = oo1.orderDate,
                                RqrtDate = rr.rqrtDate,
                                PrdnDate = s.pDate,
                                Status = s.status,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Specs = a.specs,
                                Category = cc.name,
                                PrdnType = a.prdnType,
                                DetailDprtName = dd1.name,
                                ReleaseDate = a.releaseDate,
                                PlanOutput = a.planOutput,
                                FinishNum = a.finishNum,
                                MaterialMemo = m.memo,
                                AssessorName = uu1.name,
                                DetailMemo = a.memo,
                                DepartmentName = dd.name,
                                OperatorName = uu.name,
                                DetailId = a.id
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 新增生产单
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int AddProduction(TB_Production obj)
        {
            try
            {
                dc.TB_Production.InsertOnSubmit(obj);
                dc.SubmitChanges();
                return obj.id;
            }
            catch { }
            return 0;
        }

        /// <summary>
        /// 更新生产单
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool UpdateProduction(TB_Production obj)
        {
            try
            {
                var o = dc.TB_Production.SingleOrDefault(d => d.id == obj.id);
                Common.objEval(obj, o, new List<string> { typeof(TB_PrdnDetail).Name });

                if (o.TB_PrdnDetail != null)
                {
                    foreach (TB_PrdnDetail pd in o.TB_PrdnDetail)
                    {
                        if (pd.TB_PrdnWorkstage != null)
                        {
                            foreach (TB_PrdnWorkstage pw in pd.TB_PrdnWorkstage)
                            {
                                if (pw.TB_PrdnMaterial != null)
                                    dc.TB_PrdnMaterial.DeleteAllOnSubmit(pw.TB_PrdnMaterial);
                                //pw.TB_PrdnMaterial.Clear();//清除原生产材料数据
                            }
                            //pd.TB_PrdnWorkstage.Clear();//清除原生产工序数据
                            dc.TB_PrdnWorkstage.DeleteAllOnSubmit(pd.TB_PrdnWorkstage);
                        }
                    }
                    //o.TB_PrdnDetail.Clear();//清除原明细数据
                    dc.TB_PrdnDetail.DeleteAllOnSubmit(o.TB_PrdnDetail);
                }

                if (obj.TB_PrdnDetail != null)
                {
                    foreach (TB_PrdnDetail pd in obj.TB_PrdnDetail)
                    {
                        TB_PrdnDetail nPd = new TB_PrdnDetail();
                        Common.objEval(pd, nPd, new List<string> { typeof(TB_Material).Name, typeof(TB_Production).Name, typeof(TB_PrdnWorkstage).Name });
                        if (pd.TB_PrdnWorkstage != null)
                        {
                            foreach (TB_PrdnWorkstage pw in pd.TB_PrdnWorkstage)
                            {
                                TB_PrdnWorkstage nPw = new TB_PrdnWorkstage();
                                Common.objEval(pw, nPw, new List<string> { typeof(TB_PrdnDetail).Name, typeof(TB_PrdnMaterial).Name, typeof(TB_Workstage).Name });
                                if (pw.TB_PrdnMaterial != null)
                                {
                                    foreach (TB_PrdnMaterial pm in pw.TB_PrdnMaterial)
                                    {
                                        TB_PrdnMaterial nPm = new TB_PrdnMaterial();
                                        Common.objEval(pm, nPm, new List<string> { typeof(TB_Material).Name, typeof(TB_PrdnWorkstage).Name });
                                        nPw.TB_PrdnMaterial.Add(nPm);
                                    }
                                }
                                nPd.TB_PrdnWorkstage.Add(nPw);
                            }

                        }
                        o.TB_PrdnDetail.Add(nPd);
                    }
                }

                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 删除生产单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteProduction(int id)
        {
            try
            {
                var data = dc.TB_Production.SingleOrDefault(d => d.id == id);
                data.deleteFlag = true;
                dc.SubmitChanges();
                return true;
            }
            catch { }
            return false;
        }

        #endregion

        #region 生产单明细
        /// <summary>
        /// 获取单个带关联的生产单明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public XPrdnDetail GetXPrdnDetail(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_PrdnDetail>();
                predicate = predicate.And(p => p.id == id);

                var query = from r in (dc.TB_PrdnDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id
                            join c in dc.TB_Options on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join o in dc.TB_OrderDetail on r.orderDetailId equals o.id into t_orderDetail
                            from oo in t_orderDetail.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XPrdnDetail()
                            {
                                PrdnDetail = r,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                CategoryName = cc.name,
                                MaterialName = m.cnName,
                                Unit = m.unit,
                                PrdtPrjtCode = m.projectCode,
                                TraderName = oo.TB_Order.TB_Trader.name
                            };
                return query.SingleOrDefault();

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据生产单Id获取相关的明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<XPrdnDetail> GetXPrdnDetails(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_PrdnDetail>();
                predicate = predicate.And(p => p.prdn == id);

                var query = from r in (dc.TB_PrdnDetail.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id
                            join c in dc.TB_Options on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            join o in dc.TB_OrderDetail on r.orderDetailId equals o.id into t_orderDetail
                            from oo in t_orderDetail.DefaultIfEmpty()
                            join d in dc.TB_Department on r.department equals d.id into t_department
                            from dd in t_department.DefaultIfEmpty()
                            select new XPrdnDetail()
                            {
                                PrdnDetail = r,
                                DepartmentCode = dd.code,
                                DepartmentName = dd.name,
                                CategoryName = cc.name,
                                MaterialName = m.cnName,
                                Unit = m.unit,
                                PrdtPrjtCode = m.projectCode,
                                TraderName = oo.TB_Order.TB_Trader.name
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 根据明细获取明细相关的带关联的生产工序
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>        
        public IEnumerable<XPrdnWorkstage> GetXPrdnWorkstages(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_PrdnWorkstage>();
                predicate = predicate.And(p => p.prdnDetailId == id);

                var query = from r in (dc.TB_PrdnWorkstage.Where(predicate))
                            join w in dc.TB_Workstage on r.workstage equals w.id
                            select new XPrdnWorkstage()
                            {
                                PrdnWorkstage = r,
                                WorkstageCode = w.code,
                                WorkstageName = w.name,
                                ManhourUnit = w.manhourUnit
                            };
                return query;

            }
            catch { }
            return null;
        }

        /// <summary>
        /// 更加生产工序获取相关的带关联的材料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<XPrdnMaterial> GetXPrdnMaterials(int id)
        {
            try
            {
                var predicate = PredicateBuilder.True<TB_PrdnMaterial>();
                predicate = predicate.And(p => p.prdnWorkstageId == id);

                var query = from r in (dc.TB_PrdnMaterial.Where(predicate))
                            join m in dc.TB_Material on r.material equals m.id
                            join c in dc.TB_Options on m.category equals c.id into t_category
                            from cc in t_category.DefaultIfEmpty()
                            select new XPrdnMaterial()
                            {
                                PrdnMaterial = r,
                                MaterialCode = m.code,
                                MaterialName = m.cnName,
                                Category = cc.name,
                                Specs = m.specs,
                                Expire = m.expire,
                                Unit = m.unit

                            };
                return query;

            }
            catch { }
            return null;
        }
        #endregion

        #region 需求发放
        /// <summary>
        /// 需求发放
        /// </summary>
        /// <param name="method">1、按毛需求，2-按净需求</param>
        /// <param name="op">操作员</param>
        /// <param name="dept">部门</param>
        /// <param name="issueDate">发放日期</param>
        /// <param name="rqrtId">需求Id</param>
        /// <param name="rqrtDetailIds">需求明细Id,以英文逗号分隔的Id字符窜，如："1,2,3"</param>
        /// <returns></returns>
        public bool IssueRequirement(int method, int op, int? dept, DateTime issueDate, int rqrtId, string rqrtDetailIds)
        {
            try
            {
                bool? ok = false;
                dc.IssueRequirement(method, op, dept, issueDate, rqrtId, rqrtDetailIds, ref ok);
                return Convert.ToBoolean(ok);
            }
            catch { }
            return false;
        }
        #endregion
        #endregion

        #endregion
    }
}
